很好的博文http://younglab.blog.51cto.com/416652/274132!
一直没有搞懂jquery中的事件是怎么添加事件处理程序的。原来就是用了事件委托,关键就是通过冒泡方式实现在最高层(document)处理事件,通过判断事件target的id,给以不同的handler。当然也可以通过事件捕获来处理,但是因为ie中只有冒泡,所以还是用冒泡兼容性更好一些。
细细总结一下:
1.冒泡与捕获。
冒泡和捕获是两个完全不同的事件流传播方式,当点击页面上某个元素时,不知道用户是对该元素感兴趣还是对该元素的父元素该兴趣?为此提出了两种不同的事件流模型。一种是捕获,由网景提出的,首先是最不具体的元素接收到事件,然后再一级一级传播到最具体的元素。另一种是冒泡,是由ie提出的,它和捕获完全相反,首先是最具体的元素接收到事件,然后一级一级传播到最不具体的元素,一般都是document。
2.事件委托
上面的参考博文写得很清楚了。大概模式就是这样(以onclick为例子,其他事件mouseover mousemove mouseout mousedown mouseup click dbclick keyup keydown)
document.οnclick=function(event){
var event=event?event:window.event;
var target=event.target?event.target:event.srcElement;
switch(target.id){
case:'btnid1':
btnid1handler();
break;
case:'btnid2':
btnid2handler();
break;
}
};
3.ie事件和dom(2)事件模型
ie事件模型的事件流只包括事件冒泡,而dom(2)事件模型的事件流包括三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。ie8以下的版本只支持ie事件模型,ie9及其他浏览器都支持dom事件流。
区别:
(1)添加事件处理程序的不同。dom0级只能在冒泡阶段调用事件处理程序。dom2级事件模型通过addEventListener支持在冒泡和捕获阶段注册事件处理程序。而ie事件模型通过attachEvent在事件冒泡阶段注册事件处理程序。
(2)事件处理程序的event参数和this的作用域不同。addEventListener中的this就指向当前事件元素,event就是当前事件对象。而attachEvent的this指向window,event是全局对象作用域window中的event对象,但是同时也会作为参数直接传递给事件处理程序函数。但是在只支持ie事件模型的浏览器中通过dom0级方法注册的事件处理程序中的event,只能通过全局的window.event进行访问,但无论在哪个浏览器中,通过dom0级注册的事件处理程序中的this也是指向当前事件元素,可以做到很好的跨浏览器兼容。
(3) 移除事件监听。通过dom0级注册的事件处理程序,通过 element.οnclick=null;这样的形式来移除注册事件。通过dom2级事件注册的时间处理程序通过removeEventListener来移除事件处理程序,而ie事件模型通过datachEvent来移除。
(4)阻止默认事件模型和阻止事件冒泡的方法。dom2级可以通过preventDefault来阻止事件的默认行为。ie通过returnValue属性为false来阻止事件的默认行为。dom2采用stopPropagation方法来阻止冒泡,而ie通过cancelBubble属性为true来阻止冒泡。
4 鼠标事件
A表示B元素的外部,B表示元素,C表示B的子元素
鼠标事件有以下几种:
mouseover:从A到B时触发,冒泡
mouseenter:从A到B时触发,并且不冒泡,DOM3级出现的事件
mouseleave:从B到A时触发,并且不冒泡,DOM3级出现的事件
mouseout:从B到A,或者从C到B时触发,冒泡
mousemove:B到B时触发
mousedown:按下任意鼠标按钮时触发
mouseup:释放鼠标按钮时触发
click:在同一个元素相继触发mousedown和mouseup才会触发click事件,任意一个被取消,都不会触发click
dbclick:连续两次click才能触发dbclick。