|
Выделить интервал элементов (от a до b) двумя кликами
Выделить интервал=промежуток=цепочк у элементов двумя кликами.
<!doctype html> <meta charset='utf-8'> <title>EXAMPLE</title> <div id='box'> <div class='el'>1</div> <div class='el'>2</div> <div class='el'>3</div> <div class='el'>4</div> <div class='el'>5</div> <div class='el'>6</div> <div class='el'>7</div> <div class='el'>8</div> <div class='el'>9</div> <div class='el'>X</div> </div> <style> body { display: flex; margin: 0; height: 100vh; background: #56bddc; } #box { display: flex; margin: auto; box-shadow: 0 0 5px hsla(0, 0%, 0%, .25); } .el { width: 60px; line-height: 60px; font-family: consolas; font-size: 30px; text-align: center; cursor: pointer; background: #fff; -webkit-user-select: none; -moz-user-select: none; } .el:hover { background: #fece9a; } .mark { background: #fece9a; } </style> Неужели в JavaScript нет такой конструкции: (from a to b) { ... }, где a - элемент, с которого начинается выделение, b - элемент, на котором заканчивается выделение. Итак, :write: : Например, требуется выделить интервал элементов со 2 по 7 включительно. Тогда делаем всего два клика: 1) клик по элементу номер 2; 2) клик по элементу номер 7. Результат: 2,3,4,5,6,7 элементы изменят свой цвет согласно полученному классу .mark ( см. <style> ). Тогда алгоритм будет такой: 1) клик по элементу a: -> получить номер элемента в контейнере #box; -> присвоить элементу класс .a; -> записать номер в переменную a 2) клик по элементу b: -> получить номер элемента в контейнере #box; -> присвоить элементу класс .b -> записать номер в переменную b 3) присвоить элементам от a до b класс .mark, пробежавшись по ним циклом Хотелось бы решить задачу, используя последние фишки ES6 и желательно обойтись без массивов. Цикл for-of, который может перебирать коллекции элементов, а не только массивы: http://frontender.info/es6-in-depth-...ikollektsiyami Попытки, что-то сделать: Получение номера (индекса) элемента в контейнере: box.onmouseover = function(e) { var target = e.target; target.onclick = function() { target.classList.add('a'); for (var i = 0; i < box.children.length; i++) { if (box.children[i] == target) return console.log(i + 1); } } } Может пригодится: 'use strict' var i, j = i + 1, parent = box, children = parent.children; // Вместо children можно использовать элементы от a до b parent.onmouseover = function() { for (i of children) { i.classList.add('mark'); } } На Киберфоруме я уже задавал этот вопрос, но ответ получился слишком громоздким. Надеюсь здесь удастся решить иначе. Если кому будет интересно, результат должен быть таким: http://www.cyberforum.ru/post8673990.html Надеюсь, что вы поможете. Спасибо. |
Не знаю ни ES6, ни цикла for of. Однако можно же просто запоминать ноды старта и энда, а далее используя обход по дереву добавлять соответствующие классы к нужным элементам (включая граничные).
|
destus,
можно, но я уже выбился из сил, поэтому и создал тему на этом форуме. Задача вроде не сложная, но сделать не удается. Учусь. Но наверное, я просто перегрузил голову, надо больше отдыхать. Просьба. Комментируйте предлагаемые решения, чтобы все было понятно. Спасибо. |
Teamur,
вариант без промежуточного выделения , только по клику <!DOCTYPE HTML> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style> body { display: flex; margin: 0; height: 100vh; background: #56bddc; } #box { display: flex; margin: auto; box-shadow: 0 0 5px hsla(0, 0%, 0%, .25); } .el { width: 60px; line-height: 60px; font-family: consolas; font-size: 30px; text-align: center; cursor: pointer; background: #fff; -webkit-user-select: none; -moz-user-select: none; } .el:hover { background: #fece9a; } .mark { background: #fece9a; } </style> <script> window.addEventListener("DOMContentLoaded", function() { var d = document.querySelectorAll(".el"), a = void 0; [].forEach.call(d, function(c, b) { c.addEventListener("click", function() { if (void 0 == a) a = b; else { var c = Math.min(b, a), e = Math.max(b, a); a = void 0; [].forEach.call(d, function(a, b) { b >= c && b <= e && a.classList.toggle("mark") }) } }) }) }); </script> </head> <body> <div id='box'> <div class='el'>1</div> <div class='el'>2</div> <div class='el'>3</div> <div class='el'>4</div> <div class='el'>5</div> <div class='el'>6</div> <div class='el'>7</div> <div class='el'>8</div> <div class='el'>9</div> <div class='el'>X</div> </div> </body> </html> |
рони, Спасибо.
Можно ли сделать так, чтобы третий клик, запускал функцию заново = начать новое выделение? |
Если долго не думать
<div id='box'> <div id='e1' class='el'>1</div> <div class='el'>2</div> <div class='el'>3</div> <div class='el'>4</div> <div class='el'>5</div> <div class='el'>6</div> <div class='el'>7</div> <div class='el'>8</div> <div class='el'>9</div> <div class='el'>X</div> </div> <style> body { display: flex; margin: 0; height: 100vh; background: #56bddc; } #box { display: flex; margin: auto; box-shadow: 0 0 5px hsla(0, 0%, 0%, .25); } .el { width: 60px; line-height: 60px; font-family: consolas; font-size: 30px; text-align: center; cursor: pointer; background: #fff; -webkit-user-select: none; -moz-user-select: none; } .el:hover { background: #fece9a; } .mark { background: #fece9a; } </style> <script> function positionChild(node) { var pos = 1; for (var x = node.parentNode.firstChild; x != null; x = x.nextSibling, pos++ ) { if ( x.id == node.id && x.nodeType == 1 ) { return pos; break; } } } function addClassName(obj,name) { obj.className += name; } function byPass(startDiv,endDiv) { for ( var x = startDiv; x != endDiv.nextSibling ; x = x.nextSibling ) { addClassName(x,' mark'); } } var start, end; document.getElementById('box').onclick=function fn(e){ e = e || event; var target = e.target; if (!start) { start = true; target.id = 'start'; } else { var startChildPosition, endChildPosition; if (!end) { end = true; if (target.id == 'start') { addClassName(target, ' mark'); } else { target.id = 'end'; } } startDiv = document.getElementById('start'); endDiv = document.getElementById('end'); startChildPosition = positionChild(startDiv); endChildPosition = positionChild(endDiv); if (startChildPosition < endChildPosition) byPass(startDiv,endDiv); else byPass(endDiv,startDiv) } } </script> |
destus,
Как вариант. Тоже думал насчет nextSibling. ) |
выделение диапазона элементов по двум кликам
Цитата:
<!DOCTYPE HTML> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style> body { display: flex; margin: 0; height: 100vh; background: #56bddc; } #box { display: flex; margin: auto; box-shadow: 0 0 5px hsla(0, 0%, 0%, .25); } .el { width: 60px; line-height: 60px; font-family: consolas; font-size: 30px; text-align: center; cursor: pointer; background: #fff; -webkit-user-select: none; user-select: none; -moz-user-select: none; } .el:hover { background: #fece9a; } .mark { background: #fece9a; }</style> <script> window.addEventListener("DOMContentLoaded", function() { function e(a, c) { [].forEach.call(b, function(f, d) { (d >= a && d <= c || void 0 === a) && f.classList[void 0 === a ? "remove" : "add"]("mark") }) } var b = document.querySelectorAll(".el"), a = void 0; [].forEach.call(b, function(b, c) { b.addEventListener("click", function() { if (void 0 === a) a = c, e(); else { var b = Math.min(c, a), d = Math.max(c, a); a = void 0; e(b, d) } }) }) }); </script> </head> <body> <div id='box'> <div class='el'>1</div> <div class='el'>2</div> <div class='el'>3</div> <div class='el'>4</div> <div class='el'>5</div> <div class='el'>6</div> <div class='el'>7</div> <div class='el'>8</div> <div class='el'>9</div> <div class='el'>X</div> </div> </body> </html> |
рони, замечательно.
Самое сложное, как я считаю, будет реализовать визуализацию следования выделения за курсором после первого клика по аналогии с выделением текста, когда двигая курсор после зажатия левой кнопки мыши мы ВИДИМ процесс выделения (синяя область). Спасибо |
Цитата:
|
Часовой пояс GMT +3, время: 20:18. |
|