如何使用attachEvent引用调用者对象(“t​​his”)

发布于 2024-10-10 08:29:40 字数 653 浏览 3 评论 0原文

在IE中使用.attachEvent()方法,如何用this引用调用者对象(触发事件的元素)?在普通浏览器中,使用.addEventListener,var this指向元素,而在IE中它指向窗口对象。

我需要它与以下代码一起工作:

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, funct);
     //where the value of "this" in funct should point to "element"
   }
}

我刚刚编写了该代码,它与我的代码完全不一样,但如果它可以与它一起工作,那么它就可以与我一起工作!

Using the method .attachEvent() in IE, how can I reference the caller object (the element that triggered the event) with this? In normal browsers, using .addEventListener, the var this points to the element, while in IE it points to the window object.

I need it to work with the following code:

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, funct);
     //where the value of "this" in funct should point to "element"
   }
}

I just made that code up, it's not exactly the same as my code, but if it works with it then it works with me!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

橘味果▽酱 2024-10-17 08:29:40

来自这篇 quirksmode 文章中关于 attachEvent 的内容:

  1. 事件总是冒泡,没有捕获的可能性。
  2. 事件处理函数是引用的,而不是复制的,因此 this 关键字始终引用窗口,完全没有用处

这两个弱点的结果是,当事件冒泡时,不可能知道当前是哪个 HTML 元素处理该事件。我在活动订单页面上更全面地解释了这个问题。

由于 Microsoft 事件添加模型仅受 Windows 上的 Explorer 5 及更高版本支持,因此它不能用于跨浏览器脚本。但即使对于仅在 Windows 上使用资源管理器的应用程序,最好也不要使用它,因为在复杂的应用程序中,冒泡问题可能会非常严重。

我还没有测试过它,但可能的解决方法是将处理程序包装在一个匿名函数中,该函数通过 funct.call() 调用您的处理程序。

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

对于未经测试的解决方案,我深表歉意。我不喜欢这样做,但现在无法轻松访问 IE。

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.

茶花眉 2024-10-17 08:29:40

如果您使用的是 IE,则可以通过访问事件处理函数中的 window.event.srcElement 来获取您所称的“调用者”对象。该对象通常称为事件目标

var funct = function(event) {
    if ( !event ) {
        event = window.event;
    }

    var callerElement = event.target || event.srcElement;

    // Do stuff
};

该代码未经测试,但应该会让您朝着正确的方向前进。

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.

述情 2024-10-17 08:29:40

绑定它。好吧,您不能使用 javascript 1.8.5 中添加的 Function.prototype.bind,但您可以使用闭包和 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);
     });
   }
}

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);
     });
   }
}
辞旧 2024-10-17 08:29:40

我认为扩展 Element 对象 会更好, 通过原型链,而不是将您的方法添加到要添加事件的每个元素(适用于所有浏览器)。

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"
   }
};

这样它将适用于您当前的所有 浏览器和未来的元素(并且您只需运行一次)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文