关于IE下attachEvent不能绑定this的问题

关于IE下attachEvent

不能绑定this

的问题

由于帖子"关于IE和Firefox下event乱谈

"的回复中有好人提到IE下attachEvent

不能绑定this

的问题,并给出了一些解决方案,这里收集一段代码:
js 代码
 
  1. /**

     
  2.   * Crossbrowser event handling functions.

     
  3.   *

     
  4.   * A set of functions to easily attach and detach event handlers to HTML elements.

     
  5.   * These functions work around the shortcomings of the traditional method 
      * ( element.onevent = function; )


     
  6.   * where only 1 handler could be attached for a certain event on the object, and
      * mimic the DOM level 2


     
  7.   * event methods addEventListener and removeEventListener for browsers that do not 
      * support these


     
  8.   * methods (e.g. Internet Explorer) without resorting to propriety methods such as
      * 

    attachEvent

     and detachEvent

     
  9.   * that have a whole set of their own shortcomings.

     
  10.   * Created as an entry for the 'contest' at quirksmode.org: 
      * http://www.quirksmode.org/blog/archives/2005/09/addevent_recodi.html


     
  11.   *

     
  12.   * @author Tino Zijdel ( crisp@xs4all.nl )

     
  13.   * @version 1.0

     
  14.   * @date 2005-09-09

     
  15.   */

      
  16.   
  17.   
  18. /**
  19.   * addEvent

     
  20.   *

     
  21.   * Generic function to attach event listeners to HTML elements.

     
  22.   * 
    This

     function does NOT use 
    attachEvent

     but creates an own stack of function 
      * references


     
  23.   * in the DOM space of the element. 
    This

     prevents closures and therefor possible 
      * memory leaks.


     
  24.   * Also because of the way the function references are stored they will get executed 
      * in the


     
  25.   * same order as they where attached - matching the behavior of addEventListener.

     
  26.   *

     
  27.   * @param obj The object to which the event should be attached.

     
  28.   * @param evType The eventtype, eg. 'click', 'mousemove' etcetera.

     
  29.   * @param fn The function to be executed when the event fires.

     
  30.   * @param useCapture (optional) Whether to use event capturing, or event bubbling 
      * (default).


     
  31.   */

      
  32. function


     addEvent(obj, evType, fn, useCapture)   
  33. {   
  34.     
    //-- Default to event bubbling

      
  35.     
    if


     (!useCapture) useCapture = 
    false


    ;   
  36.   
  37.     
    //-- DOM level 2 method

      
  38.     
    if


     (obj.addEventListener)   
  39.     {   
  40.         obj.addEventListener(evType, fn, useCapture);   
  41.     }   
  42.     
    else


      
  43.     {   
  44.         
    //-- event capturing not supported

      
  45.         
    if


     (useCapture)   
  46.         {   
  47.             alert('This

     browser does not support event capturing!');   
  48.         }   
  49.         
    else


      
  50.         {   
  51.             
    var


     evTypeRef = '__' + evType;   
  52.   
  53.             
    //-- create function stack in the DOM space of the element; seperate stacks for each 
      event type


      
  54.             
    if


     (!obj[evTypeRef])   
  55.             {   
  56.                 
    //-- create the stack if it doesn't exist yet

      
  57.                 obj[evTypeRef] = [];   
  58.   
  59.                 
    //-- if there is an inline event defined store it in the stack

      
  60.                 
    var


     orgEvent = obj['on'+evType];   
  61.                 
    if


     (orgEvent) obj[evTypeRef][0] = orgEvent;   
  62.   
  63.                 
    //-- attach helper function using the DOM level 0 method

      
  64.                 obj['on'+evType] = IEEventHandler;   
  65.             }   
  66.             
    else


      
  67.             {   
  68.                 
    //-- check if handler is not already attached, don't attach the same function twice to match 
    behavior of addEventListener


      
  69.                 
    for


     (
    var


     ref 
    in


     obj[evTypeRef])   
  70.                 {   
  71.                     
    if


     (obj[evTypeRef][ref] === fn) 
    return


    ;   
  72.                 }   
  73.             }   
  74.   
  75.             
    //-- add reference to the function to the stack

      
  76.             obj[evTypeRef][obj[evTypeRef].length] = fn;   
  77.         }   
  78.     }   
  79. }   
  80.   
  81. /**
  82.   * removeEvent

     
  83.   *

     
  84.   * Generic function to remove previously attached event listeners.

     
  85.   *

     
  86.   * @param obj The object to which the event listener was attached.

     
  87.   * @param evType The eventtype, eg. 'click', 'mousemove' etcetera.

     
  88.   * @param fn The listener function.

     
  89.   * @param useCapture (optional) Whether event capturing, or event bubbling 
      * (default) was used.


     
  90.   */

      
  91. function


     removeEvent(obj, evType, fn, useCapture)   
  92. {   
  93.     
    //-- Default to event bubbling

      
  94.     
    if


     (!useCapture) useCapture = 
    false


    ;   
  95.   
  96.     
    //-- DOM level 2 method

      
  97.     
    if


     (obj.removeEventListener)   
  98.     {   
  99.         obj.removeEventListener(evType, fn, useCapture);   
  100.     }   
  101.     
    else


      
  102.     {   
  103.         
    var


     evTypeRef = '__' + evType;   
  104.   
  105.         
    //-- Check if there is a stack of function references for 
    this

     event type on the object

      
  106.         
    if


     (obj[evTypeRef])   
  107.         {   
  108.             
    //-- iterate through the stack

      
  109.             
    for


     (
    var


     ref 
    in


     obj[evTypeRef])   
  110.             {   
  111.                 
    //-- if function reference is found, remove it

      
  112.                 
    if


     (obj[evTypeRef][ref] === fn)   
  113.                 {   
  114.                     
    try


      
  115.                     {   
  116.                         
    delete


     obj[evTypeRef][ref];   
  117.                     }   
  118.                     
    catch


    (e)   
  119.                     {   
  120.                         obj[evTypeRef][ref] = 
    null


    ;   
  121.                     }   
  122.   
  123.                     
    return


    ;   
  124.                 }   
  125.             }   
  126.         }   
  127.     }   
  128. }   
  129.   
  130. /**
  131.   * IEEventHandler

     
  132.   * 

     
  133.   * IE helper function to execute the attached handlers for events.

     
  134.   * Because of the way 
    this

     helperfunction is attached to the object (using the DOM 
      * level 0 method)


     
  135.   * the '
    this

    ' keyword will correctely point to the element that the handler was 
      * defined on.


     
  136.   *

     
  137.   * @param e (optional) Event object, defaults to window.event object when not passed
      * as argument (IE).


     
  138.   */

      
  139. function


     IEEventHandler(e)   
  140. {   
  141.     e = e || window.event;   
  142.     
    var


     evTypeRef = '__' + e.type;   
  143.   
  144.     
    //-- check if there is a custom function stack defined for 
    this

     event type on the object

      
  145.     
    if


     (
    this



    [evTypeRef])   
  146.     {   
  147.         
    //-- iterate through the stack and execute each function in the scope of the object by using
     function.call


      
  148.         
    for


     (
    var


     ref 
    in


     
    this



    [evTypeRef])   
  149.         {   
  150.             
    if


     (Function.call)   
  151.             {   
  152.                 
    this



    [evTypeRef][ref].call(
    this



    , e);   
  153.             }   
  154.             
    else


      
  155.             {   
  156.                 
    //-- IE 5.0 doesn't support call or apply, so use 
    this



      
  157.                 
    this



    .__fn = 
    this



    [evTypeRef][ref];   
  158.                 
    this



    .__fn(e);   
  159.                 
    this



    .__fn = 
    null


    ;   
  160.             }   
  161.         }   
  162.     }   
  163. }  
此条目发表在article分类目录,贴了标签。将固定链接加入收藏夹。