【问题标题】:IEs understanding of 'this'IE 对“this”的理解
【发布时间】:2009-09-23 15:49:08
【问题描述】:

在这段代码中,Firefox 将“this”视为被点击的元素,并通过正确的方式传递 href 属性。

IE 似乎认为 'this' 是 [object window] 而不是。我怎样才能让它在两个浏览器中以相同的方式工作?

注意:jQuery 会很可爱,但不是这个项目的选择

var printElem = getElementsByClassName('print', 'a');
for(i in printElem){
    ObserveEvent(printElem[i], 'click', function(e){
        window.open(this.href, '', 'location=0,menubar=1,resizable=1,scrollbars=1,width='+810+',height='+700);
        cancelEvent(e);
    });
}

【问题讨论】:

  • 这段代码存在于事件处理程序中?
  • 你的ObserveEvent函数是什么?
  • 如果是这样,它必须是 this 引用的元素(这可能与触发事件的元素不同,因为大多数事件都是冒泡的——非常方便的区别)。
  • 嗯...不确定它是从哪个版本提取的,但它可能在发生时被破坏了。

标签: javascript internet-explorer javascript-events


【解决方案1】:

你可以使用event target,像这样:

    ObserveEvent(printElem[i], 'click', function(e){
            var target = e.target || e.srcElement;
            window.open(target.href, '', 'location=0,menubar=1,resizable=1,scrollbars=1,width='+810+',height='+700);
            cancelEvent(e);
    });

【讨论】:

  • 该死的......我大部分时间都在那里,我有 e.target 我错过了 e.srcElement 部分。谢谢
  • 如果printElem[i] 包含孩子并且点击了那些之一,这将失败。
  • 好吧,以后你可以写一个contains函数来判断目标元素是否在printElem[i]中。但如果它没有任何孩子,请保持简单;)
  • @Alexander:contains 实现有什么帮助?您需要遍历 up 到单击的锚点。所有这一切都可以通过ObserveEvent 实现解决,该实现保留对this 的引用,就像最初提出的问题一样。
  • @crescentfresh:如果我能说服老板,改用 jQuery/任何其他完整的 javascript 框架将是有益的
【解决方案2】:

我在这里加上我的两分钱,因为我认为你可以使用它。

有一个contest 4 years ago 看看谁能写出最好的addEvent 实现。它试图解决的主要问题之一是在事件处理程序中保留this。

这里是 jQuery 创建者写的one contest entry:

function addEvent( obj, type, fn ) {
  if ( obj.attachEvent ) {
    obj['e'+type+fn] = fn;
    obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
    obj.attachEvent( 'on'+type, obj[type+fn] );
  } else
    obj.addEventListener( type, fn, false );
}

(当然要对称):

function removeEvent( obj, type, fn ) {
  if ( obj.detachEvent ) {
    obj.detachEvent( 'on'+type, obj[type+fn] );
    obj[type+fn] = null;
  } else
    obj.removeEventListener( type, fn, false );
}

如果您愿意,可以将其重命名为“ObserveEvent”。

你有它,一个 8 行的实现,你可以放入你的代码库 - 没有库,没有框架。你的处理程序中的this 引用工作得很好。

【讨论】:

  • 酷,谢谢!我仍然很想过渡到一个框架以增加代码的一致性。
  • +1 from me :) 原型不依赖于方法吗?即补丁安全吗?
  • @Alexander: 非常感谢你 :) 我想我知道你的意思。我不容忍修补原型库,不。然而,当我阅读这个问题时,我认为他们只是从原型内部撕掉了代码,在这种情况下,他们可以将自己的代码修补到他们心中的内容。
  • 是的@crescentfresh,你是对的,在我加入公司之前,它被毫不客气地撕掉了
  • 对于addEvent这样简单的事情,无需依赖函数反编译。
【解决方案3】:

这个问题几乎可以肯定源于使用 IE 的 attachEvent 方法的 ObserveEvent 函数,该方法(与其他浏览器中的 addEventListener 不同)没有将 this 设置为在事件处理程序中观察到的对象。

【讨论】:

    【解决方案4】:

    另一个选项:创建一个闭包来为每个元素的处理程序设置元素范围:

    var printElem = getElementsByClassName('print', 'a');
    for(var i in printElem){
      (function(elem) { // elem === printElem[i] at time of execution later
        ObserveEvent(elem, 'click', function(e){
          window.open(elem.href, '', 'location=0,menubar=1,resizable=1,scrollbars=1,width='+810+',height='+700);
          cancelEvent(e);
        });
      })(printElem[i]); // immediately call the temp function with our element
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 1970-01-01
      • 2019-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多