我具有以下结构:
<ul id="list-items">
<li class="item" data-id="123" data-title="Some Title">
<div class="block">
<img src="#"/>
<a href="#">Link</a>
<p>Some excerpt</p>
</div>
</li>
</ul>
<li>
项目data-
属性都在<li>
元素上使用jQuery,我通常会使用事件委托,而不是在每个<li>
项目上附加事件处理程序:
$( document ).on( 'click', '.item', function() {
var id = $( this ).data( 'id' );
var title = $( this ).data( 'title' );
});
但是,我无法使用Pure JavaScript复制此代码。
我希望能够单击一个<li>
项目而不单击其任何子元素。
由于我们必须提供对IE11的支持,因此我也不愿意使用closest()。有没有更简单的方法来实现它?
编辑:
我避免将事件侦听器附加到每个<li>
项目,因为它不适用于动态创建的<li>
元素,并且出于性能原因。
答案 0 :(得分:2)
您可以通过将li
设置为pointer-events: none
来禁用<li class="item" data-id="123" data-title="Some Title">
<div class="block" style="pointer-events: none">
<img src="#"/>
<a href="#">Link</a>
<p>Some excerpt</p>
</div>
</li>
的内容。
event.target
您现在可以保证li
始终是{{1}}
答案 1 :(得分:1)
如果您不想直接在所有项目上附加事件处理程序。您只能像这样在父级上附加一个事件处理程序
var element = document.querySelector("#vanilla-parent")
element.addEventListener("click", function(event){
event.composedPath().forEach(function(elm){
if (elm.tagName === 'LI') {
// do something
}
});
});
$("#jquery-parent").on("click", "li", function(event){
// do something
});
笔展示相同:https://codepen.io/kireeti-tiki/pen/EzPpqZ?editors=1010
我在事件对象上使用了compositionPath来获取li,我不建议这样做,因为这是一种获取解决方案的方法。另外,IE和Edge不支持它。因此,如果您需要这些浏览器的支持,请远离该解决方案。有关该主题的更多信息,请点击https://developer.mozilla.org/en-US/docs/Web/API/Event
如果使用jQuery没问题,那么我推荐这种方法。
答案 2 :(得分:0)
会像让所有li并附加事件监听器一样吗?
<script>
var li_list = document.getElementsByTagName('li');
for(var i = 0; i < li_list.length; i++) {
(function(index) {
li_list[index].addEventListener("click", function() {
event.preventDefault();
alert('clicked')
})
})(i);
}
</script>
答案 3 :(得分:0)
下面是一个使用Element.closest()的示例,其中有一个polyfill。
function attachClickHandler() {
const list = document.querySelector('.list');
list.addEventListener('click', (item) => {
// console.log('Item:', item);
const closest = item.target.closest('li');
console.log('Closest li:', closest);
console.log('Data on closest li:', closest.tagName, closest.dataset && closest.dataset.id || 'no data');
// alternative
console.log(' === alt ===');
let elem = item.target;
while (elem.tagName.toLowerCase() !== 'li') {
elem = elem.parentNode;
if (elem.tagName.toLowerCase() === 'ul') {
break;
}
}
console.log('Manual version:', elem.tagName, elem.dataset && elem.dataset.id || 'no data');
});
console.log('Listening.');
}
attachClickHandler();
<h1>My list</h1>
<ul class="list">
<li data-id="1">Item 1</li>
<li data-id="2"><button>Item 2</button></li>
<li>Empty item</li>
</ul>
编辑:这在IE上不起作用,因为stackoverflow可能不会加载polyfill。但是,如果您独立测试它(应该工作3秒钟),则可以验证它是否对您足够好。