JavaScript 事件侦听器内联与显式

JavaScript Event Listener Inline vs. Explicit

我正在使用 Tampermonkey 进行一些网页操作和自动化。为此,我向 window“加载”事件添加了一个事件侦听器。当我将事件处理程序定义为显式函数时,它会按预期顺利运行,即只要加载相关页面就会调用该函数。

window.addEventListener("load", run());

function run() {
    // do something
}

但是,当我如下定义内联处理程序时

window.addEventListener("load", function (){
     // do something
});

然后我需要在函数执行前多次刷新/重新加载页面。

为什么会有如此不同的行为?无论是像第一个示例中那样“显式”定义函数,还是像第二个示例中那样“内联”定义函数,我都不会期望有什么区别。因为我之前没有注意到这一点,所以我什至不知道这是 Tampermonkey 问题还是 Javascript 问题。

window.addEventListener("load", run()); 不会 运行 load 上的 run 函数,但会立即将 run 返回的值用作回调(这是可能 undefined)。这是 addEventListener calls the function without me even asking it to

的副本

关于:

then I need to refresh / reload the page several times before the function gets executed.

然后您可能会延迟注册事件侦听器(在页面可能已经加载的时候)。

I don't even know whether this is a Tampermonkey issue or a Javascript one.

其中 none 个,您认为网站在您注册加载事件时尚未加载是错误的假设。

您想拥有类似于 jQuery 的 ready 函数的东西,可以在此处找到没有 jQuery 的示例实现 $(document).ready equivalent without jQuery.

Tl;Dr: 传递你的函数,不要执行它。让 "load" 侦听器处理程序改为执行它:

window.addEventListener("load", run);

run() 执行你的函数,默认情况下returns undefined:*window.addEventListener("load", undefined); // and executed. *

window.addEventListener("load", run()); // run() executes immediately

function run() {
  // do something
}

如果 run() returns 另一个函数 — 这样就可以了

window.addEventListener("load", run()); // run() executes immediately  
                                        // but returns a function in its place.

function run() {
  return function() {
    // do something
  }
}

因为现在你没有通过 undefined — 但实际 function.