2016-04-20 152 views
0

我有一個附加到容器的事件偵聽器,我想過濾被點擊的內容。使用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」實現的。你可以用這個polyfill來正常化行爲https://gist.github.com/elijahmanor/6452535 – Duopixel