2016-04-20 3 views
0

У меня есть прослушиватель событий, прикрепленный к контейнеру, и я хочу фильтровать то, что нажали.Событие bubbling with querySelector

В приведенном ниже примере я отфильтровываю UL.head кликов.

<div> 
<ul class="head"> 
    <li data-test="...">1</li> 
    <li>2</li> 
    <li>3</li> 
</ul> 
<ul class="head"> 
    <li>1</li> 
    <li>2</li> 
    <li data-test="...">3</li> 
</ul> 
<ul class="head"> 
    <li>1</li> 
    <li data-test="...">2</li> 
    <li>3</li> 
</ul> 
</div> 

document.querySelector('div').addEventListener('click', function(e) { 

    var ul = findParentByClass(e.target, ".head"); 
    if(ul) { // clicke a UL } 

}); 

function findParentByClass(node, cls) { 
    while (node && !hasClass(node, cls)) { 
     node = node.parentNode; 
    } 
    return node; 
} 

Я хотел воспроизвести аналогичную функцию в findParentByClass, но это было бы findParentByQuerySelector. Так что я мог бы сделать что-то вроде:

li = findParentByQuerySelector('li:[data-test]'); 
if(li) { // clicked li with data-test attribute } 

Я проковылял о том, как я мог бы реализовать querySelector в это событие барботажа.

ответ

1

Вы можете просто использовать Element.matches метод:

function findParentBySelector(node, selector) { 
    while (node && !node.matches(selector)) { 
     node = node.parentNode; 
    } 
    return node; 
} 

Однако, обратите внимание, что реализация этого метода, к сожалению противоречивой.

В качестве альтернативы вы можете использовать более распространенный Element.querySelectorAll, который соответствует детям указанного элемента. Это означает, что вам необходимо учитывать бабушек и дедушек, а также родителей:

function findParentBySelector(node, selector) { 
    while (node && node.parentNode) { 
     let list = node.parentNode.querySelectorAll(selector); 
     if (Array.prototype.includes.call(list, node)) { 
      return node 
     } 
     node = node.parentNode; 
    } 
    return node; 
} 

Но я бы точно не назвал этот метод симпатичным.

+0

Как это непоследовательно? – ditto

+0

@ditto прочитал документацию, связанную мной; не все браузеры реализуют это, а некоторые реализуют его под другим именем. – Hamms

+0

@ditto. Первоначально он был реализован с префиксами поставщиков: «mozMatchesSelector», «msMatchesSelector», «oMatchesSelector», 'webkitMatchesSelector'. Вы можете нормализовать поведение с этим полифоном https://gist.github.com/elijahmanor/6452535 – Duopixel

Смежные вопросы