It is very common to bind event listening functions to DOM elements in Javascript, but there are also many bugs. Various browsers provide many methods for event binding, but only three of them are reliable:
1. Traditional binding methods:
ELEM. onclick= Function(Event ){
Alert (event. Type+ 'This. innerhtml');
};
A. The traditional binding method is very simple and stable. This in the function body also points to the node that is processing the event (such as the node that is currently running the event handle ).
B. An event handle of an element can only register one function. If it is registered repeatedly, overwrite is generated. In addition, the traditional binding method only runs in event bubbles.
2. W3C standard binding method:
VaR ELEM = Document. getelementbyid ( ' ID ' );
ELEM. addeventlistener ( ' Click ' ,
Function (Event ){
Alert (event. Type + ' ' + This . Innerhtml + 1 );
},
False // Bubble stage execution
);
ELEM. addeventlistener ( ' Click ' ,
Function (Event ){
Alert (event. Type + ' ' + This . Innerhtml + 2 );
},
False
);
A. This binding method supports both capture and bubble phases of time processing. The same event handle of the same element can register multiple listening functions. In addition, this inside the listening function points to the current element.
B. However, the popular IE browser does not support this registration method.
3. ie event handle registration method:
VaR ELEM = Document. getelementbyid ( ' A ' );
ELEM. attachevent ( ' Onclick ' ,
Function (){
Alert (window. event. srcelement. innerhtml + ' ' + This . Innerhtml + 1 );
}
);
ELEM. attachevent ( ' Onclick ' ,
Function (){
Alert (window. event. srcelement. innerhtml + ' ' + This . Innerhtml + 2 );
}
);
A. This binding method can be registered multiple times for the same event handle.
B. The event model of IE does not support event capture. This In the listener function points to a non-current element, and window. event. srcelement points to the node where an event occurs, rather than the current node, and there is no equivalent Dom currenttarget attribute in the event object of IE.
4. cross-browser Method 1:
Code
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 ;
};
AboveCodeBy having Dean edwardsaddevent/removeeven
5. cross-browser Method 2:
Code
Function Addevent (OBJ, type, FN ){
If (Obj. attachevent ){
OBJ [ ' E ' + Type + FN] = FN;
OBJ [Type + FN] = Function () {OBJ [ ' E ' + Type + FN] (window. Event );}
OBJ. attachevent ( ' On ' + Type, OBJ [Type + FN]);
} Else
OBJ. addeventlistener (type, FN, False );
}
Function Removeevent (OBJ, type, FN ){
If (Obj. detachevent ){
OBJ. detachevent ( ' On ' + Type, OBJ [Type + FN]);
OBJ [Type + FN] = Null ;
} Else
OBJ. removeeventlistener (type, FN, False );
}