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

IT技术 javascript internet-explorer dom this
2021-02-20 11:17:57

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

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

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

我刚刚编写了该代码,它与我的代码并不完全相同,但是如果它适用于它,那么它也适用于我!

4个回答

来自这篇关于quirksmode 的文章attachEvent

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

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

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

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

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

对于未经测试的解决方案,我深表歉意。我不喜欢那样做,但现在不能轻易进入 IE。

我之前尝试过,但我只是想出了我做错了什么。非常感谢!帕特里克ftw!!!XD
2021-04-20 11:17:57
@JCOC611:不客气,但我对您将addAnEvent函数直接附加到element. 我认为将元素作为第三个参数传递给一个单独的函数会更有用。由于我的解决方案涉及element变量,因此可能会失败。如果您将其称为element.addAnEvent( 'click', thefunc ),那么您应该将上面的解决方案更改为funct.call( this )不过,我会考虑一种不同的方法。
2021-04-25 11:17:57
@JCOC611:刚刚更新了我的答案。我的潜在代码解决方案第一次落后了。如果那不起作用,那么是的,我认为经典的方式将是后备。
2021-05-08 11:17:57
别担心,我想我知道我在做什么,哈哈,在call方法中使用“this”而不是变量是我做错的,因为在 IE 中,匿名函数中的“this”也引用了 window 对象
2021-05-08 11:17:57
所以我应该使用经典的方式而不是使用它element.onevent=function吗?(例如element.onmouseup……)
2021-05-15 11:17:57

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

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

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

    // Do stuff
};

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

工作极其顺畅。谢谢你。
2021-05-18 11:17:57

绑定它。好吧,您不能使用Function.prototype.bind在 javascript 1.8.5 中添加的那个,但是您可以使用闭包和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);
     });
   }
}
哦,我怎么会想念帕特里克的回答。
2021-05-01 11:17:57

我认为最好通过原型链扩展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"
   }
};

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

@JCOC,上面的代码在 IE、FF、Chrome、Safari 和 Opera 中进行了测试。
2021-04-23 11:17:57
@Tim,确实......它是针对 IE8+ 的,一般来说,它通过原型链扩展 DOM 对象是不受欢迎的
2021-04-26 11:17:57
是的,我知道 JS 原型设计。不过,我的代码不需要原型设计。我正在做一个相当于 jQuery 的$()功能。此外,我敢打赌原型设计并不完全跨浏览器兼容。
2021-05-14 11:17:57