事件对象详解
《事件对象》
一、事件对象的定义
在触发DOM上的某个事件时,会产生一个事件对象event。这个对象中包含着所有与事件有关的信息。包括导致事件的元素,事件的类型以及其他与特定事件相关的信息。
事件对象只能够被自身的事件处理程序(函数)进行捕获,并且一旦事件处理程序(函数)执行完毕的时候,就会自动释放事件对象。
二、事件对象的捕获
事件对象的捕获,是通过在事件处理程序中,加入一个参数event。
一定要注意的是,事件对象只能在事件处理函数中才能够被使用,其它情况下返回值都会是undefined或是null。
需要了解事件对象在不同的浏览器之间的兼容性问题:
事件对象在 IE Chrome中是全局的,附加在window对象下的,因此可以直接在事件处理函数中这样使用:
var e = event; // IE&&Chrome可以支持event的全局定义。
但是事件对象在FF中是不支持全局的,必须要通过在事件处理函数的第一个参数以传参的形式传递到事件处理函数中,即:
DomObject.event = function(e){var e = e } // FF只支持传参的形式来向事件处理函数中传入event对象
因此我们便需要进行兼容性的处理,最常见的方式:
1 DomObject.event=function(e){ 2 3 var e = e || window.event 4 5 }
最后在经过我的简化,可以写成这样的形式,即在参数的名字上做手脚
DomObject.event = function(event){ event //这样便可以兼容所有的浏览器了。 } /* *这种方法下,FF可以根据传参来兼容. *FF&IE 可以通过全局的事件对象event来兼容 */
三、事件的绑定
1. HTML指定:
<input type="button" onclick="alert(event.type)"></div>
在HTML指定中,事件对象的名称必须是event,否则浏览器便无法识别。
2. DOM0级绑定:
DOMObject.event=function(event){}
3. DOM2级绑定:
DOMObject.addEventListener('event',function(event){},isBubble); /* * 标准的事件绑定方法 * * FF、Chrome、IE9+支持 * * isBubble : 值是逻辑值,用于判断是冒泡模式还是捕获模式 */ DOMObject.attachEvent('event',function((event)){}); /* * IE私有的事件绑定方法 * */
注意:
ddEventListener是标准下的DOM2级事件添加方法,而attachEvent是IE专有的事件添加方法,这二者的区别有:
· 标准下事件类型不需要加on,而IE私有的则需要在事件名之前加on
· 标准下事件处理函数中的this指向的是绑定事件对象的DOM元素,而在IE的私有下,则代表了window对象。
· 标准下支持事件的冒泡与捕获 - 通过boolean
最终,针对以上的区别,我编写了一个简单的事件绑定的兼容函数:
function bindEvent(obj,event,fn,isBubble){ if(document.addEventListener){ obj.addEventListener(event,fn,isBubble); }else{ obj.attachEvent('on'+event,function(){ // 非标准的IE下不支持事件的捕获 fn.call(obj) /* * call方法可以执行指定函数,并且call方法的第一个参数,可以修改所执行函数的this指向。 * 因此使用此方法便可以解决非标准IE下this指向window的问题。 */ }) } }
四、事件的冒泡与捕获
1. 事件冒泡的概念:
事件冒泡就是指,当DOM元素触发了其绑定的事件时,不仅自身会去执行该事件,而且还会将事件向上依次传播其所有的父元素,一直到window或HTML为止。
事件的冒泡,与样式生成的外观没有任何关系,而与HTML中元素的结构有关系。
而上面所说的事件的绑定,实际上是一种不严谨的说法,给DOM元素绑定事件,实际上应该是给DOM元素绑定事件处理函数。这两者所代表的含义的区别是,前者会认为事件只有绑定才能够触发,而后者说明了,事件不论有没有绑定,都会被对应的操作进行触发,只是没有事件处理函数,便不会执行任何行为而已。
分别给box1,box2,bo3都添加了onclick事件,那么单击box3必然会触发事件的冒泡,导致box2与box1都执行了onclick事件。
如果现在将box2的onclick事件取消掉,那么单击box1还会将事件冒泡到box3吗?
答案是,是的,因为box2虽然没有绑定事件处理函数,但是其无任何行为的onclick事件,任然会被触发并向上进行传播。
对于这样,事件会由小的范围向其父级更大的范围乃至最后传播到整个窗口,我们可以想象成像一个小水泡,由内到外慢慢变大,这也是事件冒泡名字的由来。
2. 事件的捕获
事件捕获就是指,当DOM元素触发了其绑定的事件时,事件便回从最顶层(FF Chrome IE9+ 是 Window 而 IE 8.0 - 则会是HTML)开始,从上向下,从外到内进行事件的传播,然后一直到该元素(触发事件的元素)为止。这一事件传播的过程就是事件的 捕获。
事件捕获与事件冒泡正好相反,前者由外到内,由上到下、而后者则是由内到外,由下到上的一个过程。
事件冒泡所有浏览器都支持,但是事件捕获只有在支持addEventListener方法的浏览器中才能够被支持。
addEventListener(event,fn,isBubble) //isBubble 值分别为false,true,false表示了事件的冒泡,而true则表示了事件的捕获。
五、事件对象的属性说明:
type : 返回事件的类型。
target : 返回触发事件的DOM元素本身。IE支持相同功能属性的:srcElement。
currentTarget : 返回绑定事件的DOM元素本身。IE不支持该属性,但事件对象的this指针永远指向的都是绑定的DOM元素。
clientX | clientY : 以浏览器窗口客户区的左上角为(0,0)起始,返回鼠标在客户区的坐标值。
兼容性:FF CH IE
pageX | pageY : 以页面左上角为(0,0)起始,返回鼠标在整个页面的坐标值,当页面的尺寸超出浏览器客户区的时候,拖动滚动条,其pageX值也会发生改变。因此我们说,pageX,pageY返回的最大值也就是页面的大小。
兼容性:FF CH IE9+
pageX|Y兼容性处理:
1 function getPageCoords(event){ 2 if(event.pageX || event.pageY){ 3 return {'x':event.pageX,'y':event.pageY} 4 }else{ 5 var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; 6 var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft; 7 return {'x':event.clientX+scrollTop,'y':event.clientY+scrollLeft}; 8 } 9 } 10 11 //调用方式 12 13 document.body.onclick=function(e){ 14 var e = e || window.event; 15 var coords = getPageCoords(e); 16 alert('coords:'+coords.x+' '+coords.y); 17 }
screenX | screenY : 以屏幕的左上角为(0,0)起始。返回鼠标在浏览器客户区的坐标值。
注意:screenX 与 clientX的区别是一个以浏览器客户区为起始,一个以屏幕为起始。
IE下可能最小值会是2,而不是0,则是因为IE浏览器有一个奇葩的边框线,在浏览器的周围。
兼容性:FF CH IE
offsetX | offsetY : 该属性的参考起始位置,不在是以浏览器客户区或浏览器的左上角为起始(0,0),而是以它所绑定触发的那个DOM元素的左上角为起始,并以该元素的右下角为结束位置,然后返回鼠标在其中的坐标值。
兼容性:IE FF CH
wheelDelta : 返回值:120 | -120 ,如果滚轮向上则是正值120,向下为负值-120。
兼容性:Chrome IE
delita : 返回值:5 | -5 如果滚轮向上则是负值-5,向下为正值5
兼容性:FF
keyCode : 可以返回按键的Ascii码值。
兼容性:IE FF CH
returnValue : IE专有属性,通过returnValue=false可以取消DOM元素的默认操作。
cancelBubble : IE专有属性,通过cancelBubble=true 可以阻止事件对象的冒泡
六、事件对象的方法说明:
preventDefault() 标准事件对象方法,用于取消DOM元素的默认行为,例如a链接的跳转,div元素的滚动操作等。
stopPropagation() 标准事件对象方法,用于阻止事件的冒泡。
七、最后附加上我新学习的两个滚动事件
1. 滚轮事件:
DOM0 : onmousewheel // IE && CH支持。
DOM2 : mousewheel // CH支持 onmousewheel //IE支持 DOMMouseScroll //FF支持
下面是我编写的一个滚轮事件的兼容性函数:http://www.cnblogs.com/HCJJ/p/4896261.html
2. 滚动条事件:
事件名:onscroll
定义:滚动条事件,一旦滚动条被滚动、拖动或其值(scrollTop)发生了改变,那么就会触发滚动条事件。
注意:在使用onscroll事件的时候,一定要注意最好不要对body附加onscroll事件,因为可能会发生兼容性问题,onscroll最好的绑定对象时window
示例:window.onscroll=function(){alert('scroll')}