我正在尝试使用以下代码实现事件委派:
<html>
<head>
<script>
document.addEventListener('click', function(e){
alert(e.target.className);
}, false);
</script>
</head>
<body>
<ul class="list">
<li class="item">A</li>
<li class="item">B</li>
<li class="item">C</li>
<li class="item">D</li>
</ul>
</body>
</html>
我希望事件能够冒泡,以便当我点击<li>
项时,警报会显示item
,然后另一个警报会显示list
。但是此代码仅提供item
的警报。如何修改它以使事件冒泡?
答案 0 :(得分:1)
在document
对象上绑定单击处理程序时,不能指望多次调用它。它只会被调用一次(在document
对象上)。
事件确实冒泡了DOM树。如果没有,它将无法到达document
对象,您将看不到任何警告框。
因此,事件在LI元素处触发,然后一直冒泡到document
对象,调用单击处理程序。
顺便说一下,你通常不会一直委托给document
对象,而是委托给最近的共同祖先。例如,如果要处理LI元素的点击,则委托UL元素:
var list = document.getElementsByClassName( 'list' )[0];
list.addEventListener( 'click', function ( e ) {
var item = e.target;
// handle item click
}, false );
答案 1 :(得分:1)
您需要为列表添加事件以提醒它。事件由父对象捕获,但没有绑定到它们的事件,因此它不会发出警报。您需要为所有对象添加事件以提醒它。
答案 2 :(得分:1)
事件回调仅触发一次,但并不意味着事件不会冒泡。回调仅在元素侦听事件时执行。
如果您真的希望将警报一直触发回祖先,请在回调中逐个添加祖先的警报。您不必向所有祖先添加侦听器,这会导致消耗更多内存。
答案 3 :(得分:1)
我刚刚发布了一个小型事件委托库,以便更轻松地执行此类操作。请查看http://craig.is/riding/gators
你可以做到
Gator(document).on('click', 'li', function() { alert('li clicked!'); });
Gator(document).on('click', 'ul', function() { alert('ul clicked!'); });
这会将单击处理程序绑定到文档,并相应地调度事件。
除非您停止传播,否则当您点击li
时,它们都会触发。
答案 4 :(得分:0)
您可以使用一些循环方法来调用两个警报:
var list = document.getElementsByClassName('list')[0];
list.addEventListener("click", function (e) {
var target = e.target;
while (target !== list) {
switch(target.nodeName) {
case "LI": //alert('li clicked!')
break;
case "UL": //alert('ul clicked!')
break;
}
target = target.parentNode;
}
});