How to reference the caller object (“this”) using attachEvent

后端 未结 4 1216
温柔的废话
温柔的废话 2020-11-29 08:56

Using the method .attachEvent() in IE, how can I reference the caller object (the element that triggered the event) with this? In

相关标签:
4条回答
  • 2020-11-29 09:11

    From this quirksmode article with regard to attachEvent:

    1. Events always bubble, no capturing possibility.
    2. The event handling function is referenced, not copied, so the this keyword always refers to the window and is completely useless.

    The result of these two weaknesses is that when an event bubbles up it is impossible to know which HTML element currently handles the event. I explain this problem more fully on the Event order page.

    Since the Microsoft event adding model is only supported by Explorer 5 and higher on Windows, it cannot be used for cross–browser scripts. But even for Explorer–on–Windows only applications it’s best not to use it, since the bubbling problem can be quite nasty in complex applications.

    I haven't tested it, but a possible workaround may be to wrap the handler in an anonymous function that calls your handler via funct.call().

    else if(element.attachEvent){
       element.attachEvent("on"+name, function(){ funct.call( element ) });
    }
    

    My apologies for the untested solution. I don't like doing that, but can't easily get to IE right now.

    0 讨论(0)
  • 2020-11-29 09:15

    If you're in IE, you can get the "caller" object, as you call it, by accessing window.event.srcElement within the event handler function. This object is normally referred to as the event target or source.

    var funct = function(event) {
        if ( !event ) {
            event = window.event;
        }
    
        var callerElement = event.target || event.srcElement;
    
        // Do stuff
    };
    

    This code is untested, but should set you off in the right direction.

    0 讨论(0)
  • 2020-11-29 09:15

    I think it would be better to extend the Element object , through the prototype chain, instead of adding your method to each element you want to add events to (works with all browsers)..

    Element.prototype.addAnEvent = function(name, funct){
       if(this.addEventListener) // Works in NORMAL browsers...
       {
         this.addEventListener(name,funct, false);
       }
       else if(this.attachEvent){
         var _this = this;
         this.attachEvent("on"+name, function(){funct.apply(_this);});
         //where the value of "this" in funct should point to "element"
       }
    };
    

    This way it will work for all your current and future elements (and you only have to run it once).

    0 讨论(0)
  • 2020-11-29 09:16

    Bind it. Well, you can't use Function.prototype.bind that gets added in javascript 1.8.5, but you can use closure and Function.prototype.apply.

    var element = //the element, doesn't matter how it is obtained
    element.addAnEvent = function(name, funct){
       if(element.addEventListener) // Works in NORMAL browsers...
         //...
       else if(element.attachEvent){
         element.attachEvent("on"+name, function() {
           //call funct with 'this' == 'element'
           return funct.apply(element, arguments);
         });
       }
    }
    
    0 讨论(0)
提交回复
热议问题