事件代理也叫事件委托,原理:利用DOM元素的事件冒泡,指定一个事件的处理程序就可以管理某一类型的所有事件。
事件冒泡和事件捕获
如上图所示,事件传播分成三个阶段:
捕获阶段:从window对象传导到目标节点(上层传到底层)称为“捕获阶段”(capture phase),捕获阶段不会响应任何事件;
目标阶段:在目标节点上触发,称为“目标阶段”
冒泡阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层;
addEventListener 事件监听的三个参数
element.addEventListener(event,function,useCapture)
useCapture
第三个参数
- 默认值为冒泡
- true:代表捕获
- false或者不填:代表冒泡
事件冒泡案例
var body=document.getElementsByTagName('body')[0];
window.addEventListener('click',function(){
console.log('window')
},false)
body.addEventListener('click',function(){
console.log('body')
},false)
var oDiv=document.getElementsByTagName('div')[0];
oDiv.addEventListener('click',function(){
console.log(1)
},false)
oDiv.addEventListener('click',function(){
console.log(2)
},false)
点击div运行结果 1 2 body window
事件捕获案例
var body=document.getElementsByTagName('body')[0];
window.addEventListener('click',function(){
console.log('window')
},true)
body.addEventListener('click',function(){
console.log('body')
},true)
var oDiv=document.getElementsByTagName('div')[0];
oDiv.addEventListener('click',function(){
console.log(1)
},true)
oDiv.addEventListener('click',function(){
console.log(2)
},true)
点击div运行结果 window body 1 2
经典面试题
使用事件委托的好处
使用事件代理的好处不仅在于将多个事件处理函数减为一个,而且对于不同的元素可以有不同的处理方法。假如上述列表元素当中添加了其他的元素节点(如:a、span等),我们不必再一次循环给每一个元素绑定事件,直接修改事件代理的事件处理函数即可。
阻止事件冒泡
- 给子级加 event.stopPropagation( )
$("#div1").mousedown(function(e){
var e=event||window.event;
event.stopPropagation();
});
- 在事件处理函数中返回 false
$("#div1").mousedown(function(event){
var e=e||window.event;
return false;
});
但是这两种方式是有区别的。return false 不仅阻止了事件往上冒泡,而且阻止了事件本身(默认事件)。event.stopPropagation()则只阻止事件往上冒泡,不阻止事件本身。
- event.target==event.currentTarget,让触发事件的元素等于绑定事件的元素,也可以阻止事件冒泡;
阻止默认事件
-
event.preventDefault()
-
return false