在JavaScript中出现了MSIE和addEventListener问题?

85
document.getElementById('container').addEventListener('copy',beforecopy,false );

在Chrome / Safari中,当页面内容被复制时,以上代码将运行“beforecopy”函数。 MSIE也应该支持此功能,但出现以下错误:“对象不支持此属性或方法”。现在,我理解Internet Explorer不会使用body节点,但我认为通过ID提供节点应该可以正常工作。有人知道我做错了什么吗?
** 对于任何能告诉我第三个参数“False”有什么用处的人,将获得额外的奖励分数。

这是一篇很好的文章,非常清楚地解释了捕获阶段和useCapture:http://coding.smashingmagazine.com/2013/11/12/an-introduction-to-dom-events/#event-phases - feeela
8个回答

186

在IE中,你需要使用attachEvent而不是标准的addEventListener

一种常见的做法是检查addEventListener方法是否可用并使用它,否则使用attachEvent

if (el.addEventListener){
  el.addEventListener('click', modifyText, false); 
} else if (el.attachEvent){
  el.attachEvent('onclick', modifyText);
}
你可以编写一个函数来完成它:
function bindEvent(el, eventName, eventHandler) {
  if (el.addEventListener){
    el.addEventListener(eventName, eventHandler, false); 
  } else if (el.attachEvent){
    el.attachEvent('on'+eventName, eventHandler);
  }
}
// ...
bindEvent(document.getElementById('myElement'), 'click', function () {
  alert('element clicked');
});

您可以在此处运行上述代码的示例

addEventListener的第三个参数是useCapture;如果为true,则表示用户希望启动事件捕获


1
感谢您的回复。我刚刚尝试了您发布的内容,它起作用了。现在让我困惑的是,“复制”事件不起作用,但“单击”事件起作用。具体来说,这很奇怪,因为quirksmode指出它应该起作用:http://www.quirksmode.org/dom/events/cutcopypaste.html有什么想法吗? - Matrym
删掉那个评论。我刚刚试了一下你发的东西,把click改成copy确实可以。再次感谢。 - Matrym
1
为什么微软自己的文档显示要使用 addEventListener 呢?http://msdn.microsoft.com/en-us/library/ie/cc197015(v=vs.85).aspx - wmarbut
1
@wmarbut addEventListener应该是在IE9中添加的。attachEvent在IE11中被移除了。原始问题是来自2009年。CMS提供了正确、强大的方法,即使在IE 11中仍然可以使用。 - Colin Young
这就解释了为什么它在互联网上能够正常工作,但是在内网上却不能,因为我将我的内网站点的设置设置为兼容模式。 - Roger Perkins

33

如果您正在使用JQuery 2.x,则请在以下位置添加以下内容

<html>
   <head>
      <meta http-equiv="X-UA-Compatible" content="IE=edge;" />
   </head>
   <body>
    ...
   </body>
</html>

这对我起作用了。


4
对于那些使用IE版本<= 8的用户,这将无法解决问题。 - ninjaneer

5

Internet Explorer (IE8及以下版本) 不支持 addEventListener(...)。它有自己的事件模型,使用 attachEvent 方法。您可以使用类似以下代码的代码:

var element = document.getElementById('container');
if (document.addEventListener){
    element .addEventListener('copy', beforeCopy, false); 
} else if (el.attachEvent){
    element .attachEvent('oncopy', beforeCopy);
}

虽然我建议避免编写自己的事件处理包装器,而是使用JavaScript框架(如jQuery, Dojo, MooTools, YUI, Prototype等),避免不得不自己创建此修复。

顺便说一下,在W3C事件模型中,第三个参数与事件冒泡和事件捕获之间的区别有关。在几乎所有情况下,您都希望在事件冒泡时处理事件,而不是在事件捕获时处理事件。这在使用事件委托处理像文本框的“focus”事件这样的事件时非常有用,因为它们不会冒泡。


5
尝试添加

<meta http-equiv="X-UA-Compatible" content="IE=edge"> 

在head标签之后立即插入。

3
对于运行 IE 版本小于等于 8 的用户,这将无法解决问题。 - ninjaneer

2
自IE11起,您需要使用addEventListenerattachEvent已被弃用并会抛出错误。

0
如 PPK 在这里所指出的,在 IE 中你也可以使用。
e.cancelBubble = true;

0

使用 <meta http-equiv="X-UA-Compatible" content="IE=9">,IE9+ 可以通过移除事件名称中的 "on" 来支持 addEventListener,例如:

 var btn1 = document.getElementById('btn1');
 btn1.addEventListener('mousedown', function() {
   console.log('mousedown');
 });

0
问题在于IE浏览器不支持标准的addEventListener方法,而是使用其自己的attachEvent方法,两者实现的功能基本相同。
了解关于这两者之间区别的好的解释可以在quirksmode中找到,同时也提到了第三个参数的相关信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接