关于IE下attachEvent
不能绑定this
的问题
由于帖子"关于IE和Firefox下event乱谈
"的回复中有好人提到IE下attachEvent
不能绑定this
的问题,并给出了一些解决方案,这里收集一段代码:
"的回复中有好人提到IE下attachEvent
不能绑定this
的问题,并给出了一些解决方案,这里收集一段代码:
js 代码
-
/**
-
* Crossbrowser event handling functions.
-
*
-
* A set of functions to easily attach and detach event handlers to HTML elements.
-
* These functions work around the shortcomings of the traditional method
* ( element.onevent = function; )
-
* where only 1 handler could be attached for a certain event on the object, and
* mimic the DOM level 2
-
* event methods addEventListener and removeEventListener for browsers that do not
* support these
-
* methods (e.g. Internet Explorer) without resorting to propriety methods such as
*
attachEvent
and detachEvent
-
* that have a whole set of their own shortcomings.
-
* Created as an entry for the 'contest' at quirksmode.org:
* http://www.quirksmode.org/blog/archives/2005/09/addevent_recodi.html
-
*
-
* @author Tino Zijdel ( crisp@xs4all.nl )
-
* @version 1.0
-
* @date 2005-09-09
-
*/
-
-
-
/**
-
* addEvent
-
*
-
* Generic function to attach event listeners to HTML elements.
-
*
This
function does NOT use
attachEvent
but creates an own stack of function
* references
-
* in the DOM space of the element.
This
prevents closures and therefor possible
* memory leaks.
-
* Also because of the way the function references are stored they will get executed
* in the
-
* same order as they where attached - matching the behavior of addEventListener.
-
*
-
* @param obj The object to which the event should be attached.
-
* @param evType The eventtype, eg. 'click', 'mousemove' etcetera.
-
* @param fn The function to be executed when the event fires.
-
* @param useCapture (optional) Whether to use event capturing, or event bubbling
* (default).
-
*/
-
function
addEvent(obj, evType, fn, useCapture) -
{
-
//-- Default to event bubbling
-
if
(!useCapture) useCapture =
false
; -
-
//-- DOM level 2 method
-
if
(obj.addEventListener) -
{
-
obj.addEventListener(evType, fn, useCapture);
-
}
-
else
-
{
-
//-- event capturing not supported
-
if
(useCapture) -
{
-
alert('This
browser does not support event capturing!'); -
}
-
else
-
{
-
var
evTypeRef = '__' + evType; -
-
//-- create function stack in the DOM space of the element; seperate stacks for each
event type
-
if
(!obj[evTypeRef]) -
{
-
//-- create the stack if it doesn't exist yet
-
obj[evTypeRef] = [];
-
-
//-- if there is an inline event defined store it in the stack
-
var
orgEvent = obj['on'+evType]; -
if
(orgEvent) obj[evTypeRef][0] = orgEvent; -
-
//-- attach helper function using the DOM level 0 method
-
obj['on'+evType] = IEEventHandler;
-
}
-
else
-
{
-
//-- check if handler is not already attached, don't attach the same function twice to match
behavior of addEventListener
-
for
(
var
ref
in
obj[evTypeRef]) -
{
-
if
(obj[evTypeRef][ref] === fn)
return
; -
}
-
}
-
-
//-- add reference to the function to the stack
-
obj[evTypeRef][obj[evTypeRef].length] = fn;
-
}
-
}
-
}
-
-
/**
-
* removeEvent
-
*
-
* Generic function to remove previously attached event listeners.
-
*
-
* @param obj The object to which the event listener was attached.
-
* @param evType The eventtype, eg. 'click', 'mousemove' etcetera.
-
* @param fn The listener function.
-
* @param useCapture (optional) Whether event capturing, or event bubbling
* (default) was used.
-
*/
-
function
removeEvent(obj, evType, fn, useCapture) -
{
-
//-- Default to event bubbling
-
if
(!useCapture) useCapture =
false
; -
-
//-- DOM level 2 method
-
if
(obj.removeEventListener) -
{
-
obj.removeEventListener(evType, fn, useCapture);
-
}
-
else
-
{
-
var
evTypeRef = '__' + evType; -
-
//-- Check if there is a stack of function references for
this
event type on the object
-
if
(obj[evTypeRef]) -
{
-
//-- iterate through the stack
-
for
(
var
ref
in
obj[evTypeRef]) -
{
-
//-- if function reference is found, remove it
-
if
(obj[evTypeRef][ref] === fn) -
{
-
try
-
{
-
delete
obj[evTypeRef][ref]; -
}
-
catch
(e) -
{
-
obj[evTypeRef][ref] =
null
; -
}
-
-
return
; -
}
-
}
-
}
-
}
-
}
-
-
/**
-
* IEEventHandler
-
*
-
* IE helper function to execute the attached handlers for events.
-
* Because of the way
this
helperfunction is attached to the object (using the DOM
* level 0 method)
-
* the '
this
' keyword will correctely point to the element that the handler was
* defined on.
-
*
-
* @param e (optional) Event object, defaults to window.event object when not passed
* as argument (IE).
-
*/
-
function
IEEventHandler(e) -
{
-
e = e || window.event;
-
var
evTypeRef = '__' + e.type; -
-
//-- check if there is a custom function stack defined for
this
event type on the object
-
if
(
this
[evTypeRef]) -
{
-
//-- iterate through the stack and execute each function in the scope of the object by using
function.call
-
for
(
var
ref
in
this
[evTypeRef]) -
{
-
if
(Function.call) -
{
-
this
[evTypeRef][ref].call(
this
, e); -
}
-
else
-
{
-
//-- IE 5.0 doesn't support call or apply, so use
this
-
this
.__fn =
this
[evTypeRef][ref]; -
this
.__fn(e); -
this
.__fn =
null
; -
}
-
}
-
}
-
}