人心 2019-06-21
在说事件委托之前,先介绍一下事件冒泡。
根据红宝书,事件开始是由最具体的元素接受,然后逐级传播到较为不具体的节点
例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div></div> </body> </html>
如果单击了div,则click事件会按照如下顺序传播
(1)div
(2)body
(3)html
(4)document
因为事件冒泡的原理,我们就可以将事件绑定在不具体的父元素上,点击具体的子元素,触发其父元素的事件,这就是事件委托。
事件委托就是讲事件监听器加在所要绑定元素的父元素上,为避免给每个特定的节点增加事件监听,避免在特定节点被删除时还要再删除它的绑定事件。
例子:
<ul id="parent-list"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <li>Item 4</li> <li>Item 5</li> <li>Item 6</li> </ul> // 找到父元素,添加监听器... document.getElementById("parent-list").addEventListener("click",function(e) { // e.target是被点击的元素! // 如果被点击的是li元素 if(e.target && e.target.nodeName == "LI") { // do something } });
然后,再介绍jQuery事件委托。
这是我在调用bootstrap框架时要使用bootstrap的日历控件
<input type="text" class="datetimepicker">
发现如果是动态添加的元素,无法为新添加的元素增加事件,所以是无效的,所以我们应该将点击生成日历控件这个方法绑定在它的父元素上,使用jQuery中的on方法
$(selector).on(event,childSelector,data,function,map),
具体实现:
$parent.on("focus",".datetimepicker",function(){ $(this).datetimepicker({ language: 'fr', format:'yyyy-mm-dd', todayBtn: 1, autoclose: 1, todayHighlight: 1, startView: 2, minView: 2, forceParse: 0 }); }); 还有一个方法是live(),不过在jQuery1.7中已被废弃,由on()取代,就不提啦。