|
Выделить интервал элементов (от 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, время: 06:19. |
|