<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .selected { background: #0f0; } li { cursor: pointer; } </style> </head> <body> Клик на элементе выделяет только его. <br> Ctrl(Cmd)+Клик добавляет/убирает элемент из выделенных. <br> Shift+Клик добавляет промежуток от последнего кликнутого к выделению. <br> <ul> <li>Кристофер Робин</li> <li>Винни-Пух</li> <li>Ослик Иа</li> <li>Мудрая Сова</li> <li>Кролик. Просто кролик.</li> </ul> <script> var ul = document.querySelector('ul');// получили весь список var lastClickedLi = null; // --- обработчики --- ul.onclick = function(event) { var target = event.target; // возможно, клик был внутри списка UL, но вне элементов LI if (target.tagName != "LI") return; // для Mac проверяем Cmd, т.к. Ctrl + click там контекстное меню if (event.metaKey || event.ctrlKey) { toggleSelect(target); } else if (event.shiftKey) { selectFromLast(target); } else { selectSingle(target); } lastClickedLi = target; }; ul.onmousedown = function() { return false; }; // --- функции для выделения --- function toggleSelect(li) { li.classList.toggle('selected'); } function selectFromLast(target) { var startElem = lastClickedLi || ul.children[0]; var isLastClickedBefore = startElem.compareDocumentPosition(target) & 4; if (isLastClickedBefore) { for (var elem = startElem; elem != target; elem = elem.nextElementSibling) { elem.classList.add('selected'); } } else { for (var elem = startElem; elem != target; elem = elem.previousElementSibling) { elem.classList.add('selected'); } } elem.classList.add('selected'); } function deselectAll() { for (var i = 0; i < ul.children.length; i++) { ul.children[i].classList.remove('selected'); } } function selectSingle(li) { deselectAll(); li.classList.add('selected'); } </script> </body> </html> 

Interested in this line, why is "4" here ????

 var isLastClickedBefore = startElem.compareDocumentPosition(target) & 4; 

2 answers 2

Read the description of the compareDocumentPosition function:

 nodeA.compareDocumentPosition(nodeB); 

The return value is a bitmask, the bits in which mean the following:

 000100 4 nodeA предшествует nodeB 

Further, & in JavaScript is “bitwise AND ”, and x & 4 will return a non-zero value if the third bit is set to x , i.e. if a

nodeA precedes nodeB

So the code

 var isLastClickedBefore = startElem.compareDocumentPosition(target) & 4; 

puts a non-zero value in the isLastClickedBefore variable if and only if startElem precedes the target element.

    The line allows you to find out in which direction you need to go over the elements in order to select all that were between the previous selected and the current one.

    There is a check of which element is higher in the DOM tree, the one that was clicked on or the one that was active before.

    It turns out that if the lowest one was chosen and we select the one that is higher, then we go up through all the elements and select the elements between them.



      Source: https://ru.stackoverflow.com/questions/546731/


      All Articles