attachEvent和addEventListener详解,开始了!
一、基础篇
先介绍 attachEvent:
attachEvent方法可以动态的为网页内的元素添加一个事件,通常你想为某个按扭添加一个单击事件时.你都会在按扭内写上onclick=事件名称,使用attachEvent则不必这样做.你把写好的事件准备好,在需要的时候给元素绑定上再执行.而且attachEvent支持为某个元素绑定多个事件.执行顺序是,后绑定的先执行。
那么我在什么时候使用该方法呢,当然在你需要时,不过如今的Web2.0追求的是分离式开发技术,也就是说你在网页内看不到一句JavaScript语句,却在该页中使用了大量JavaScript技术,这就是高手们所谓的分离式开发技术,让前端的显示和程序逻辑分离开来。
如果想删除事件请使用detachEvent
attachEvent方法只支持IE浏览器.与其功能相同的指令是addEventListener,该指令支持FF等浏览器,并且是W3C标准
具体请参看下面实例:
语法:Element.attachEvent(Etype,EventName)
返回值:[tag:return_value /]
参数Element:要为该元素动态添加一个事件。
Etype:指定事件类型.比如:onclick,onkeyup,onmousemove等。
EventName:指定事件名称.也就是你写好的函数。
attachEvent实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <html> <head> <title>attachEvent方法使用实例</title> </head> <body> <input id="a" type="button" value="点我" />注意该按扭没有任何事件<br/> <input id="b" type="button" value="点我绑定事件" onclick="att_Event()" />点击该按扭为上面的按扭添加一个事件. <center><h3>重点提示:你可以尝试多次点击绑定事件,最上面的那个按扭就会绑定多个事件.比如你点击三次绑定.你再点击最上面的按扭,他就会执行三次弹出框.这就是我说的attachEvent方法支持为某个元素绑定多个事件.当然在实际开发中,你可以根据实际情况,来为他绑定多个不同的事件! <script language="javascript"> function att_Event(){ var a = document.getElementById("a"); a.value = "点我有事件"; a.attachEvent("onclick",Hello_ok); }
function Hello_ok(){ alert("您好,欢迎来到grycheng的博客!本博客的发展离不开您的支持,谢谢您光临!"); } </script> </body> </html>
|
接下来:addEventListener
addEventListener方法与attachEvent方法功能相同,但是addEventListener是W3C标准,而>attachEvent非W3C标准,且只支持IE浏览器。虽然addEventListener属于标准方法,但依然无法在IE下运行,IE不支持该方法。
addEventListener带有三个参数.必须设置,缺一不可。
addEventListener可以为网页内某个元素动态绑定一个事件.事件类型可随意指定.如:click,mousemove,keyup等。
通常你想为某个按扭添加一个单击事件时。你都会在按扭内写上onclick=事件名称,使用addEventListener则不必这样做。你把写好的事件准备好,在需要的时候给元素绑定上再执行。而且addEventListener支持为某个元素绑定多个事件,执行顺序是:先绑定的先执行。
那么我在什么时候使用该方法呢,当然在你需要时,不过如今的Web2.0追求的是分离式开发技术,也就是说你在网页内看不到一句JavaScript语句,却在该页中使用了大量JavaScript技术,这就是高手们所谓的分离式开发技术,让前端的显示和程序逻辑分离开来。
如果想删除事件请使用removeEventListener
经过我测试该方法支持FireFox(火狐浏览器),不支持IE,具体请参看下面实例。
语法:Element.addEventListener(Etype,EventName,boole)
返回值:[tag:return_value /]
参数Element:要为该元素绑定一个事件,可以是任意的html元素。
Etype:事件类型,比如:click,keyup,mousemove,注意使用addEventListener绑定事件时,设置参数事件类型时不必写on,否则会出错。
EventName:要绑定事件的名称,也就是你写好的函数.
boole:该参数是一个布尔值,false或true必须填写,false代表支持浏览器事件捕获功能,true代表支持浏览事件冒泡功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <html> <head> <title>addEventListener方法使用实例</title> </head> <body> <input id="a" type="button" value="点我" />注意执行网页时该按扭并没有事件<br/> <input id="b" type="button" value="点我绑定事件" onclick="add_Event()" />点击该按扭为上面的按扭绑定事件<br/> <h3>注意该实例必须在FireFox(火狐浏览器下运行).你可以根据实际情况,来为他绑定多个不同的事件!addEventListener与<a href="http://hi.baidu.com/jiang_yy_jiang">attachevent</a>不一样的是,该方法不可以把同一事件绑定多次,但支持把不同的事件绑定到一个元素.请使用非IE浏览器测试该例。</h3> <script language="javascript"> function add_Event(){ var a = document.getElementById("a"); a.value="点我有事件"; a.addEventListener("click",Hello_ok,false); }
function Hello_ok(){ alert("您好!欢迎来到grycheng的博客!本博客的发展离不开您的支持,谢谢您光临!"); } </script> </body> </html>
|
请注意说明哈!那个很重要,开发人员要注意细节!
看了上面的你在想,这两个方法浏览器不兼容,咋办,当然!老办法咯!!先判断是IE还是火狐嘛,这个简单看下面代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script type="text/javascript"> function att_Event() { var a = document.getElementById("a"); a.value = "点我有事件"; if (document.all) { a.attachEvent("onclick", Hello_ok); } else { a.addEventListener("click", Hello_ok, false); } } function Hello_ok() { alert("您好,我测试attachEvent时间方法!"); } </script>
|
二、进阶篇
一般我们在JS中添加事件,是这样子的
这种绑定事件的方式,兼容主流浏览器,但如果一个元素上添加多次同一事件呢?
1 2 3
| obj.onclick=method1; obj.onclick=method2; obj.onclick=method3;
|
如果这样写,那么只有最后绑定的事件,这里是method3会被执行,这个时候我们就不能用onclick这样的写法了,主角改登场了,在IE中我们可以使用attachEvent方法
1 2 3 4
| btn1Obj.attachEvent("onclick",method1); btn1Obj.attachEvent("onclick",method2); btn1Obj.attachEvent("onclick",method3);
|
执行顺序为method1->method2->method3
做前端开发工程师,最悲剧的某过于浏览器兼容问题了,上面有两种添加事件的方法,为了同一添加事件的方法,我们不得不再重新写一个通用的添加事件函数,幸亏再有前人帮我们做了这件事
1 2 3 4 5 6 7 8 9 10 11 12 13
| function addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture); return true; } else if (elm.attachEvent) { var r = elm.attachEvent(‘on‘ + evType, fn); return r; } else { elm['on' + evType] = fn; } }
|
下面是Dean Edwards 的版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| function addEvent(element, type, handler) {
if (!handler.$$guid) handler.$$guid = addEvent.guid++;
if (!element.events) element.events = {};
var handlers = element.events[type]; if (!handlers) { handlers = element.events[type] = {};
if (element["on" + type]) { handlers[0] = element["on" + type]; } }
handlers[handler.$$guid] = handler;
element["on" + type] = handleEvent; };
addEvent.guid = 1; function removeEvent(element, type, handler) {
if (element.events && element.events[type]) { delete element.events[type][handler.$$guid]; } }; function handleEvent(event) { var returnValue = true;
event = event || fixEvent(window.event);
var handlers = this.events[event.type];
for (var i in handlers) { this.$$handleEvent = handlers[i]; if (this.$$handleEvent(event) === false) { returnValue = false; } } return returnValue; };
function fixEvent(event) {
event.preventDefault = fixEvent.preventDefault; event.stopPropagation = fixEvent.stopPropagation; return event; }; fixEvent.preventDefault = function() { this.returnValue = false; }; fixEvent.stopPropagation = function() { this.cancelBubble = true; };
|
功能非常强悍,解决IE的this指向问题,event总是作为第一个参数传入,跨浏览器就更不在话下。
最后贡献一个HTML5工作组的版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| var addEvent=(function(){ if(document.addEventListener){ return function(el,type,fn){ if(el.length){ for(var i=0;i&lt;el.length;i++){ addEvent(el[i],type,fn); } }else{ el.addEventListener(type,fn,false); } }; }else{ return function(el,type,fn){ if(el.length){ for(var i=0;i&lt;el.length;i++){ addEvent(el[i],type,fn); } }else{ el.attachEvent(‘on‘+type,function(){ return fn.call(el,window.event); }); } }; } })();
|
PS:IE的attachEvent和W3C标准的addEventListener绑定多个事件的执行顺序是不一样的!