一般我们在JS中添加事件,是这样子的
这种绑定事件的方式,兼容主流浏览器,但如果一个元素上添加多次同一事件呢?
如果这样写,那么只有最后绑定的事件,这里是method3会被执行,这个时候我们就不能用onclick这样的写法了,主角改登场了,在IE中我们可以使用attachEvent方法
2 | btn1Obj.attachEvent( "onclick" ,method1);
|
3 | btn1Obj.attachEvent( "onclick" ,method2);
|
4 | btn1Obj.attachEvent( "onclick" ,method3); |
使用格式是前面是事件类型,注意的是需要加on,比如onclick,onsubmit,onchange,执行顺序是
method3->method2->method1
可惜这个微软的私人方法,火狐和其他浏览器都不支持,幸运的是他们都支持W3C标准的addEventListener方法
2 | btn1Obj.addEventListener( "click" ,method1, false );
|
3 | btn1Obj.addEventListener( "click" ,method2, false );
|
4 | btn1Obj.addEventListener( "click" ,method3, false ); |
执行顺序为method1->method2->method3
做前端开发工程师,最悲剧的某过于浏览器兼容问题了,上面有两种添加事件的方法,为了同一添加事件的方法,我们不得不再重新写一个通用的添加事件函数,幸亏再有前人帮我们做了这件事
01 | function
addEvent(elm, evType, fn, useCapture) { |
02 | if
(elm.addEventListener) { |
03 | elm.addEventListener(evType, fn, useCapture); |
06 | else
if (elm.attachEvent) { |
07 | var
r = elm.attachEvent(‘on‘ + evType, fn); |
11 | elm[ 'on'
+ evType] = fn; |
下面是Dean Edwards 的版本
01 | function
addEvent(element, type, handler) { |
03 | if
(!handler.$$guid) handler.$$guid = addEvent.guid++; |
05 | if
(!element.events) element.events = {}; |
07 | var
handlers = element.events[type]; |
09 | handlers = element.events[type] = {};
|
11 | if
(element[ "on"
+ type]) { |
12 | handlers[0] = element[ "on"
+ type]; |
16 | handlers[handler.$$guid] = handler;
|
18 | element[ "on"
+ type] = handleEvent; |
22 | function
removeEvent(element, type, handler) { |
24 | if
(element.events && element.events[type]) { |
25 | delete
element.events[type][handler.$$guid]; |
28 | function
handleEvent(event) { |
29 | var
returnValue = true ;
|
31 | event = event || fixEvent(window.event);
|
33 | var
handlers = this .events[event.type];
|
35 | for
( var i
in handlers) {
|
36 | this .$$handleEvent = handlers[i];
|
37 | if
( this .$$handleEvent(event) ===
false ) {
|
44 | function
fixEvent(event) { |
46 | event.preventDefault = fixEvent.preventDefault;
|
47 | event.stopPropagation = fixEvent.stopPropagation;
|
50 | fixEvent.preventDefault =
function () {
|
51 | this .returnValue =
false ;
|
53 | fixEvent.stopPropagation =
function () {
|
54 | this .cancelBubble =
true ;
|
功能非常强悍,解决IE的this指向问题,event总是作为第一个参数传入,跨浏览器就更不在话下。
最后贡献一个HTML5工作组的版本:
01 | var
addEvent=( function (){
|
02 | if (document.addEventListener){
|
03 | return
function (el,type,fn){ |
05 | for ( var
i=0;i<el.length;i++){ |
06 | addEvent(el[i],type,fn); |
09 | el.addEventListener(type,fn, false );
|
13 | return
function (el,type,fn){ |
15 | for ( var
i=0;i<el.length;i++){ |
16 | addEvent(el[i],type,fn); |
19 | el.attachEvent(‘on‘+type, function (){
|
20 | return
fn.call(el,window.event); |
可能细心的读者发现了IE的attachEvent和W3C标准的addEventListener绑定多个事件的执行顺序是不一样的