js 事件冒泡与事件捕获
一、事件冒泡
事件冒泡是指在事件发生过程中先从目标节点开始执行,并一层一层的相父节点依次查询直到document,并执行相同事件的过程。
btn1.addEventListener('click',function(e){
//true 为事件捕获,false 为事件冒泡
//false为默认方式,冒泡方式执行
//点击btn1时,如果是事件冒泡,则先执行btn1上的click事件,然后执行父元素div1上的click事件
//如果是事件捕获,则先执行父元素上的click事件,然后执行btn1上的click事件
var e= e||window.event;
alert('你点击了btn1');
},false);
div1.addEventListener('click',function(e){
alert('你点击了div1');
},false);
这样的写法,当你点击btn1的时候,先弹出“你点击了btn1”,然后弹出“你点击了div1”;
二、事件捕获
事件捕获就是在事件发生过程中,先从document开始执行相同的事件,依次一层一层查找到目标节点,然后执行相同的事件。
btn1.addEventListener('click',function(e){
//true 为事件捕获,false 为事件冒泡
//false为默认方式,冒泡方式执行
//点击btn1时,如果是事件冒泡,则先执行btn1上的click事件,然后执行父元素上的click事件
//如果是事件捕获,则先执行父元素上的click事件,然后执行btn1上的click事件
var e= e||window.event;
alert('你点击了btn1');
},true);
div1.addEventListener('click',function(e){
alert('你点击了div1');
},true);
这样的写法,当你点击btn1的时候,先弹出“你点击了div1”,然后弹出“你点击了btn1”;
三、阻止事件冒泡和事件捕获
在阻止事件冒泡和捕获方式上,IE和其他浏览器不同;
首先是event的不同;
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!
在IE中输出的event 为 event;event在IE中为全局函数,可以在任何地方调用。
在FF中输出的为event; 在FF中只能在实践中调用,把event作为参数传进函数内
其他浏览器 则为二者都可以;
所以在确定event的时候需要进行浏览器兼容
var e = event||window.event;
等同于 e = e?event:window.event;
通过这种方法,IE识别event,其他浏览器识别window.event;
在阻止事件方法上也有不同
IE:e.cancelBubble = true; 通过把e.cancelBubble设置为true,来阻止事件分发;
标准浏览器:e.stopPropagation(); 标准浏览器的stopPropagation 方法可以设置不再派发事件。
兼容代码如下:
var e = event||window.event;
if(e.stopPropagation){
e.stopPropagation();//标准浏览器
}else{
e.cancelBubble = true;//IE浏览器
}
四、事件委托方法依托事件冒泡机制
传统事件绑定
我们给每一个li绑定点击之后背景颜色变红的事件;
var uli = document.getElementById('uli');
var lis = uli.getElementsByTagName('li');
for (var i = 0;i<lis.length;i++){
lis[i].onclick = function(){
this.style.backgroundColor = 'red';
}
}
//这样我们就可以做到li上面添加鼠标事件。
//但是如果说我们可能有很多个li用for循环的话就比较影响性能。
一个事件委托实例
html不变,只更改事件绑定的方法
var uli = document.getElementById('uli');
uli.addEventListener('click',function(event){
var e = event||window.event;
var target = e.target||e.srcElement;//该方法用于查询发生event事件的具体节点。
//e.target 是标准浏览器的方法
//e.srcElement 是IE中的方法
if (target.nodeName.toUpperCase()=='LI'){
target.style.backgroundColor = 'red';
}
});
标准浏览器查询event节点的方法是:window.event.target;
IE浏览器查询event节点的方法是:event.srcElement;
这样的写法可以在点击li的时候向上冒泡至ul,然后执行ul上的绑定事件,这样就不用给每个li都绑定一个点击事件.
而且新添加的li元素也可以绑定这样的事件,不用重新绑定
可以用removeElementListener 来取消绑定的事件函数
五、绑定事件监听方法
传统绑定事件
on + click、mouseover、keyup 等
传统绑定的
优点
- 非常简单和稳定,可以确保它在你使用的不同浏览器中运作一致
- 处理事件时,this关键字引用的是当前元素,这很有帮助
缺点
绑定同样事件的多个函数会覆盖,只能触发最后一种。
uli.onclick = function(){
alert('1');
}
uli.onclick = function(){
alert('2');
}
这样的写法执行时只能执行alert('2'); 解除绑定用 uli.onclick = null;
W3C绑定事件
uli.addEventListener('click',function(){.........},false);
- W3C绑定的优点
- 该方法同时支持事件处理的捕获和冒泡阶段。事件阶段取决于addEventListener最后的参数设置:false (冒泡) 或 true (捕获)。
- 在事件处理函数内部,this关键字引用当前元素。
- 事件对象总是可以通过处理函数的第一个参数(e)捕获。
- 可以为同一个元素绑定你所希望的多个事件,同时并不会覆盖先前绑定的事件
- W3C绑定的缺点
- IE不支持,你必须使用IE的attachEvent函数替代。
解除绑定用 removeEventListener('click',fucntion(){.........});
IE绑定事件
IE用attachEvent方法绑定事件
element.attachEvent('onclick', function(){
// ...
});
- IE方式的优点
- 可以为同一个元素绑定你所希望的多个事件,同时并不会覆盖先前绑定的事件。
- IE方式的缺点
- IE仅支持事件捕获的冒泡阶段
- 事件监听函数内的this关键字指向了window对象,而不是当前元素(IE的一个巨大缺点)
- 事件对象仅存在与window.event参数中
- 事件必须以ontype的形式命名,比如,onclick而非click
- 仅IE可用。你必须在非IE浏览器中使用W3C的addEventListene
解除绑定函数用 detachEvent('onclick',fucntion(){})