JS事件总结
JS事件
总结自一篇文章:
(一)事件绑定的方式
总体为两种: html中绑定 | JS中绑定
1、html中绑定
1) <div id="outA" onclick="var id=this.id;alert(id);return false;"></div>
2) <div id="outA" onclick="return buttonHandler(this);"></div>
直接写JS代码或者一个函数调用。注意时间处理函数中的this代表window对象,所以需要通过this讲DOM对象作为参数传递。
2、JS中绑定
1) dom.onclick = function(){alert(this.id);}
函数中的this代表当前DOM对象。这种方法只能绑定一个时间处理函数,后面覆盖前面。
2) IE使用attachEvent/detachEvent函数进行事件绑定和取消。就不说了。。。
3) W3C标准方法: addEventListener/removeEventListener (IE 6/7/8 don not support)
dom.addEventListener(type, listener, useCapture)
//type:事件类型(不含on)
//listener:事件处理函数
//useCapture:默认为false,表示事件冒泡,true为事件捕获
dom.addEventListener('click', a, false);
function() {
alert(this.id);
}
a) 事件处理函数中的this代表DOM对象
b) 同一个事件处理函数可以绑定两次,但必须一次是事件捕获,一次是事件冒泡
c) 不同的listener可重复绑定
(二)事件处理函数的执行顺序
如果给同一个事件绑定多个处理函数,先绑定的先执行。
例如给outA元素绑定了多个onclick事件处理函数,在这种场景下不涉及到事件冒泡和捕获。否则执行顺序会有不同。
(三) 事件冒泡和事件捕获
<div id="outA">
<div id="outB">
<div id="outC">
</div>
</div>
</div>
//若点击了最内侧的outC,同样会触发outB和outA的点击事件,那么
//是执行A -> B -> C ? 还是 C -> B -> A ?
答案很简单:
若是事件冒泡,则是 C -> B -> A
若是事件捕获,则是 A -> B -> C
(四)DOM事件流
看图:
DOM事件流有三个阶段:捕获阶段、目标阶段、冒泡阶段
outC.addEventListener('click', function(){alert("target");}, true);
//目标
outA.addEventListener('click', function(){alert("bubble1");}, false);
outB.addEventListener('click', function(){alert("bubble2");}, false);
//冒泡阶段
outA.addEventListener('click', function(){alert("capture1");}, true);
outB.addEventListener('click', function(){alert("capture2");}, true);
//捕获阶段
当点击outC元素时,依次打印出 capture1 -> capture2 -> target -> bubble2 -> bubble1
所以,
useCapture = false 意味着: 将listener加入到冒泡阶段
useCapture = true 意味着: 将listener加入到捕获阶段
若是outC同时绑定了冒泡和捕获,则先绑定的先执行。
结论
捕获阶段的事件处理函数先执行。
其次是目标阶段的。
最后是冒泡阶段的。
目标阶段的listener,先注册的先执行。
(五)阻止事件冒泡和捕获
IE8及以前:window.event.cancelBubble = true
iE9+/FF/chrome:event.stopPropagation()