转自:http://blog.segmentfault.com/stephenlee/1190000000473293
假设这样一个场景,你需要为一个动态列表的所有 li
标签都绑定一个 click
事件,而且这个列表增删特别频繁。如果我们直接对每一个 li
标签做添加和去除监听事件的操作将是无比麻烦的。这个时候,事件委托 (Event Delegation)
的作用就凸显出来了。
通过事件委托机制,你可以给 li
的父级标签 ul
添加事件监听,但是如果事件监听是添加到父级标签的,事件又怎么知道 click
操作在那个子标签上呢?下面举例说明:
<ul id="parent-list"> <li id="post-1">Item 1</li> <li id="post-2">Item 2</li> <li id="post-3">Item 3</li> <li id="post-4">Item 4</li> <li id="post-5">Item 5</li> <li id="post-6">Item 6</li> </ul> <script> // 获得父级元素并添加 click 事件监听 document.getElementById("parent-list").addEventListener("click",function(e) { // e.target 即 click 事件发生的元素,同时判断该元素是否是一个 li 标签 if(e.target && e.target.nodeName == "LI") { // console 输出被点击的 li 标签的 id console.log("List item ",e.target.id," was clicked!"); } }); </script>
javascript
的事件委托机制很好地简化了我们的逻辑,通过对父级元素 ul
进行 click
事件监听,从而处理了父级元素下所有子元素 li
的 click
事件。整个流程如下:
首先从浏览器捕获到 click
事件的目标对象为 li
标签,然后通过 javascript
的冒泡机制往上冒泡找到 ul
标签,此时可以通过 e
的 target
属性获得真正被点击的 li
元素。
如果我们的列表变为:
<ul id="parent-list"> <li id="post-1"><span>Item 1</span></li> <li id="post-2"><span>Item 2</span></li> <li id="post-3"><span>Item 3</span></li> <li id="post-4"><span>Item 4</span></li> <li id="post-5"><span>Item 5</span></li> <li id="post-6"><span>Item 6</span></li> </ul>
此时浏览器捕获到 click
事件的目标对象变为 span
,所以如果我们希望获得 span
父元素 li
的 id
时需要通过 e.target.parentNode.id
来获得。
参考
http://davidwalsh.name/event-delegate
http://blog.segmentfault.com/fishenal/1190000000470398