【问题标题】:Difference between document.addEventListener and window.addEventListener?document.addEventListener 和 window.addEventListener 的区别?
【发布时间】:2012-08-16 05:49:12
【问题描述】:

在使用 PhoneGap 时,它有一些使用 document.addEventListener 的默认 JavaScript 代码,但我有自己的使用 window.addEventListener 的代码:

function onBodyLoad(){
    document.addEventListener("deviceready", onDeviceReady, false);
    document.addEventListener("touchmove", preventBehavior, false);
    window.addEventListener('shake', shakeEventDidOccur, false);
}

有什么区别,哪个更好用?

【问题讨论】:

    标签: javascript events dom event-listener


    【解决方案1】:

    documentwindow 是不同的对象,它们有一些不同的事件。在它们上使用addEventListener() 会监听发往不同对象的事件。您应该使用实际有您感兴趣的事件的那个。

    例如,window 对象上的"resize" 事件不在document 对象上。

    例如,"readystatechange" 事件仅在 document 对象上。

    所以基本上,您需要知道哪个对象接收到您感兴趣的事件并在该特定对象上使用.addEventListener()

    这是一个有趣的图表,显示了哪些类型的对象创建了哪些类型的事件:https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference


    如果您正在侦听传播的事件(例如单击事件),那么您可以在文档对象或窗口对象上侦听该事件。传播事件的唯一主要区别在于时间。该事件将在window 对象之前命中document 对象,因为它首先出现在层次结构中,但这种差异通常并不重要,因此您可以选择其中任何一个。我发现在处理传播的事件时,通常最好选择最接近事件源的对象以满足您的需求。这将建议您选择document 而不是window,无论哪个都可以。但是,我经常会更靠近源并在文档中使用document.body 甚至更接近的共同父级(如果可能的话)。

    【讨论】:

    • 我对“冒泡到文档而不是窗口”的事情感到好奇。所以我在这里测试了它 -> jsfiddle.net/k3qv9/1 我错过了什么还是真的发生了冒泡?
    • @JOPLOmacedo - 在您发表评论之前,我删除了关于冒泡的部分,因为我不确定哪些事件会冒泡到窗口,哪些不会。我一直看到的协议是在document.body 对象或document 对象处拦截文档范围的冒泡事件,因此没有理由将window 用于冒泡事件。无论如何,我的回答的重点是某些事件仅在 window 上,而有些事件仅在 document 上,有些在两者上,因此 OP 应该选择与他们想要处理的事件相对应的对象。
    • 好吧。这也是我通常做的事情——这正是我决定测试它的原因。感谢您的回答!
    • 因为 'click' 事件在文档和窗口中都可用,如果我们在文档和窗口上都注册事件,那么文档的点击处理程序首先触发然后是窗口。所以从这个角度来说选择文件比较好。 jsfiddle.net/3LcVw
    • 另一个例子:如果你要通过window为三星电视添加addEventListener("keydown", event),那么它就不起作用了。但是你会用document做同样的事情,然后它会的。还取决于特定设备如何调用冒泡事件。
    【解决方案2】:

    您会发现,在 javascript 中,通常有许多不同的方法可以做同样的事情或找到相同的信息。在您的示例中,您正在寻找一些保证始终存在的元素。 windowdocument 都符合要求(只有一些区别)。

    来自mozilla dev network

    addEventListener() 在单个事件上注册一个事件监听器 目标。事件目标可能是文档中的单个元素, 文档本身、窗口或 XMLHttpRequest。

    所以只要你能指望你的“目标”总是在那里,唯一的区别就是你在听什么事件,所以就用你最喜欢的吧。

    【讨论】:

    • 这通常不是真的。不同的事件发生在不同的对象上。 documentwindow 不会收到相同的事件。您必须选择获取您感兴趣的事件的对象。有些事件可能会同时发送到documentwindow,但不是全部。
    【解决方案3】:

    window 绑定是指浏览器提供的内置对象。它表示包含document 的浏览器窗口。调用其addEventListener 方法会注册第二个参数(回调函数),以便在其第一个参数描述的事件发生时调用。

    <p>Some paragraph.</p>
    <script>
      window.addEventListener("click", () => {
        console.log("Test");
      });
    </script>
    

    选择窗口或文档添加EventListners前应注意以下几点

    1. windowdocument 的大多数事件是相同的,但是 一些事件,如resize,以及与loading 相关的其他事件, unloadingopening/closing都应该设置在window上。
    2. 由于窗口有文档,所以最好使用文档来 处理(如果可以处理),因为事件将首先命中文档。
    3. Internet Explorer 不响应在 窗口,所以您需要使用文档来注册事件。

    【讨论】:

      【解决方案4】:

      在我看来,在处理传播事件时,通常最好选择最接近事件源的对象以满足您的需求。

      所以,如果你想让事件发生在元素上,最好使用window.addEventListener()(假设window变量是一个元素),因为这里监听事件最重要的是代码和事件执行工作更快:在这种情况下唯一重要的事情。

      【讨论】:

        猜你喜欢
        • 2020-06-29
        • 1970-01-01
        • 2014-09-07
        • 2013-09-28
        • 1970-01-01
        • 2017-01-01
        • 2020-12-14
        • 2020-09-29
        • 2013-08-07
        相关资源
        最近更新 更多