我有一个附加到容器的事件监听器,我想要过滤所点击的内容。
在下面的示例中,我过滤了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
。
答案 0 :(得分: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;
}
但我不会完全称呼那种方法。