JavaScript 事件委托
事件冒泡
事件传播分成三个阶段
- 捕获阶段:从 window 对象传导到目标节点(上层传到底层)称为“捕获阶段”(capture phase),捕获阶段不会响应任何事件
- 目标阶段:在目标节点上触发,称为“目标阶段”
- 冒泡阶段:从目标节点传导回 window 对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层
事件委托的优点
- 可以大量节省内存占用,减少事件注册,比如在 ul 上代理所有 li 的 click 事件
- 可以实现当新增子对象时无需再次对其绑定(动态绑定事件),比如通过 AJAX 或者用户操作动态的增加或者删除列表项 li 元素。采用事件委托,事件是绑定在父层的,和目标元素的增减是没有关系的,执行到目标元素是在真正响应执行事件函数的过程中去匹配的
具体实现
1 2 3 4 5
| <ul id="myLinks"> <li id="goSomewhere">Go somewhere</li> <li id="doSomething">Do something</li> <li id="sayHi">Say hi</li> </ul>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var item1 = document.getElementById("goSomewhere"); var item2 = document.getElementById("doSomething"); var item3 = document.getElementById("sayHi");
document.addEventListener("click", function (event) { var target = event.target; switch (target.id) { case "doSomething": document.title = "事件委托"; break; case "goSomewhere": location.href = "http://www.baidu.com"; break; case "sayHi": alert("hi"); break; } });
|
jQuery 事件 delegate()实现事件委托
delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。
1
| $(selector).delegate(childSelector, event, data, function)
|
- childSelector 必需,规定要附加事件处理程序的一个或多个子元素。
- event 必需,规定附加到元素的一个或多个事件。由空格分隔多个事件值。必须是有效的事件。
- data 可选,规定传递到函数的额外数据。
- function 必需,规定当事件发生时运行的函数。
1 2 3 4 5
| $(document).ready(function () { $("#myLinks").delegate("#goSomewhere", "click", function () { location.href = "http://www.baidu.com"; }); });
|
使用事件委托注意事项
使用“事件委托”时,并不是说把事件委托给的元素越靠近顶层就越好。事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时。如果 DOM 嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失。