javascript attachEvent 与 addEventListener

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3743446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 02:06:13  来源:igfitidea点击:

attachEvent versus addEventListener

javascriptcross-browser

提问by Léon

I'm having troubles getting the attachEvent to work. In all browsers that support the addEventListener handler the code below works like a charm, but in IE is a complete disaster. They have their own (incomplete) variation of it called attachEvent.

我在让 attachEvent 工作时遇到了麻烦。在所有支持 addEventListener 处理程序的浏览器中,下面的代码就像一个魅力,但在 IE 中是一场彻底的灾难。他们有自己的(不完整的)变体,称为 attachEvent。

Now here's the deal. How do I get the attachEvent to work in the same way addEventListener does?

现在是交易。如何让 attachEvent 以与 addEventListener 相同的方式工作?

Here's the code:

这是代码:

function aFunction(idname)
{
    document.writeln('<iframe id="'+idname+'"></iframe>');
    var Editor = document.getElementById(idname).contentWindow.document;

    /* Some other code */

    if (Editor.attachEvent)
    {
        document.writeln('<textarea id="'+this.idname+'" name="' + this.idname + '" style="display:none">'+this.html+'</textarea>');
        Editor.attachEvent("onkeyup", KeyBoardHandler);
    }
    else
    {
        document.writeln('<textarea id="hdn'+this.idname+'" name="' + this.idname + '" style="display:block">'+this.html+'</textarea>');
        Editor.addEventListener("keyup", KeyBoardHandler, true);
    }
}

This calls the function KeyBoardHandler that looks like this:

这会调用 KeyBoardHandler 函数,如下所示:

function KeyBoardHandler(Event, keyEventArgs) {
    if (Event.keyCode == 13) {
        Event.target.ownerDocument.execCommand("inserthtml",false,'<br />');
        Event.returnValue = false;
    }

    /* more code */
}

I don't want to use any frameworks because A) I'm trying to learn and understand something, and B) any framework is just an overload of code I'm nog going to use.

我不想使用任何框架,因为 A) 我正在尝试学习和理解某些东西,B) 任何框架都只是我将要使用的代码的重载。

Any help is highly appreciated!

任何帮助表示高度赞赏!

回答by user1902622

Here's how to make this work cross-browser, just for reference though.

以下是如何使这项工作跨浏览器,但仅供参考。

var myFunction=function(){
  //do something here
}
var el=document.getElementById('myId');

if (el.addEventListener) {
  el.addEventListener('mouseover',myFunction,false);
  el.addEventListener('mouseout',myFunction,false);
} else if(el.attachEvent) {
  el.attachEvent('onmouseover',myFunction);
  el.attachEvent('onmouseout',myFunction);
} else {
  el.onmouseover = myFunction;
  el.onmouseout = myFunction;
}

ref: http://jquerydojo.blogspot.com/2012/12/javascript-dom-addeventlistener-and.html

参考:http: //jquerydojo.blogspot.com/2012/12/javascript-dom-addeventlistener-and.html

回答by Tim Down

The source of your problems is the KeyBoardHandlerfunction. Specifically, in IE Eventobjects do not have a targetproperty: the equivalent is srcElement. Also, the returnValueproperty of Eventobjects is IE-only. You want the preventDefault()method in other browsers.

问题的根源在于KeyBoardHandler函数。具体来说,在 IE 中Event对象没有target属性:等价物是srcElement. 此外,对象的returnValue属性Event仅适用于 IE。您希望preventDefault()在其他浏览器中使用该方法。

function KeyBoardHandler(evt, keyEventArgs) {
    if (evt.keyCode == 13) {
        var target = evt.target || evt.srcElement;
        target.ownerDocument.execCommand("inserthtml",false,'<br />');
        if (typeof evt.preventDefault != "undefined") {
            evt.preventDefault();
        } else {
            evt.returnValue = false;
        }
    }

    /* more code */
}

回答by Crayon Violent

Just use a framework like jQuery or prototype. That's what they are there for, this exact reason: being able to do this sort of thing w/out having to worry about cross-browser compatibility. It's super easy to install...just include a .js script and add a line of code...

只需使用像 jQuery 或原型这样的框架。这就是它们存在的目的,这个确切的原因是:能够做这种事情而不必担心跨浏览器的兼容性。安装非常简单……只需包含一个 .js 脚本并添加一行代码……

(edited just for you Crescent Fresh)

(专为您编辑的 Crescent Fresh)

With a framework, the code is as simple as...

有了框架,代码就这么简单……

<script type='text/javascript' src='jquery.js'></script>
$('element').keyup(function() { 
  // stuff to happen on event here
});

回答by Mic

Here is a function I use for both browsers:

这是我用于两个浏览器的函数:

function eventListen(t, fn, o) {
    o = o || window;
    var e = t+Math.round(Math.random()*99999999);
    if ( o.attachEvent ) {
        o['e'+e] = fn;
        o[e] = function(){
            o['e'+e]( window.event );
        };
        o.attachEvent( 'on'+t, o[e] );
    }else{
        o.addEventListener( t, fn, false );
    }
}

And you can use it like:

你可以像这样使用它:

eventListen('keyup', function(ev){
  if (ev.keyCode === 13){
    ...
  }
  ...
}, Editor)

回答by Evan

Different browsers will process events differently. Some browsers have event bubble up throw the controls where as some go top down. For more information on that take a look at this W3C doc: http://www.w3.org/TR/DOM-Level-3-Events/#event-flow

不同的浏览器会以不同的方式处理事件。一些浏览器有事件冒泡抛出控件,而有些浏览器自上而下。有关更多信息,请查看此 W3C 文档:http: //www.w3.org/TR/DOM-Level-3-Events/#event-flow

As for this specific issue setting the "userCapture" parameter to false for the addEventListener will make events behave the same as Internet Explorer: https://developer.mozilla.org/en/DOM/element.addEventListener#Internet_Explorer

对于这个特定问题,将 addEventListener 的“userCapture”参数设置为 false 将使事件的行为与 Internet Explorer 相同:https: //developer.mozilla.org/en/DOM/element.addEventListener#Internet_Explorer

回答by Archimedix

You might be better off using a JavaScript framework such as MooToolsor jQueryof your choice to ease cross-browser support. For details, see also

您最好使用 JavaScript 框架,例如您选择的MooToolsjQuery,以简化跨浏览器支持。有关详细信息,另请参阅

MooTools port of parts of your sample code:

示例代码部分的 MooTools 端口:

var Editor = $(idname).contentWindow.document;
...
$(document.body).grab(new Element('textarea', {
    'id'   : this.idname,
    'name' : this.idname,
    'style': 'display:none;',
    'html' : this.html
});
Editor.addEvent('keyup', KeyBoardHandler);

By the way, is it on purpose that you use both idnameand this.idnamein the code above ?

顺便说一句,您在上面的代码中同时使用idname和是故意的this.idname吗?