JavaScript addEventListener函数

13

我对事件处理程序还不熟悉,我遇到了下面的代码

document.addEventListener("DOMContentLoaded", function() {
    initialiseMediaPlayer();
}, false);

当编写相同的代码时,是否有任何区别?

document.addEventListener("DOMContentLoaded", initialiseMediaPlayer();, false);

最终我们调用的是同一个函数,那么以以上方式编写有什么区别或优势吗?

3
后者不会做你认为的那样。 - John Dvorak
4
后者是语法错误。 - John Dvorak
1
你正在将 initialiseMediaPlayer 的返回值传递给事件监听器。移除调用 (),它们就会相同。 - danronmoon
@danronmoon 直到返回值 - John Dvorak
4个回答

46
document.addEventListener("DOMContentLoaded", function() {
    initialiseMediaPlayer();
}, false);

当DOM内容加载完成时,将执行initialiseMediaPlayer

document.addEventListener("DOMContentLoaded", initialiseMediaPlayer();, false);

是一个语法错误;如果您删除分号:

document.addEventListener("DOMContentLoaded", initialiseMediaPlayer(), false);

立即调用 initialiseMediaPlayer 函数,然后将返回值(很可能不是一个函数)传递给 addEventListener。这样做不能如预期地起作用。


你可以这样做:

    document.addEventListener("DOMContentLoaded", initialiseMediaPlayer, false);

去掉括号=函数调用。然后initialiseMediaPlayer将在dom内容加载时执行,并按预期运行。

然而,与前一种情况不同,initialiseMediaPlayer实际上会接收由浏览器提供的参数。同时,浏览器会接收它的返回值。在DOMContentLoaded的情况下,这很可能并不重要。

如果直接传递initialiseMediaPlayer,还可以避免创建额外的匿名函数。同样,从用户的角度来看,效果并不明显。


1
如果initialiseMediaPlayer接收参数会怎么样? - Fernando Montoya
@montogeek,该参数将是一个事件对象,其最显著的属性是它所指向的文档。我敢打赌初始化程序甚至不会注意到有一个事件对象被传递给它。 - John Dvorak
1
谢谢,我解决了,使用.bind解决了我的问题。 - Fernando Montoya

10

1). 是的,二者有很大区别。第二个版本会抛出一个错误。但是即使你将其修复如下:

document.addEventListener("DOMContentLoaded", initialiseMediaPlayer(), false);

initialiseMediaPlayer 不会在 DOMContentLoaded 上被调用,因为 () 会使其立即执行,而你需要传递一个 函数 的引用,而不是其结果。

2). 另一个重要的区别是 调用的上下文

document.addEventListener("DOMContentLoaded", initialiseMediaPlayer, false);

initialiseMediaPlayer将在document对象的上下文中被调用。而第一个版本将在Window对象上下文中被调用。


听起来有点混乱,但它使事情更清晰。非常感谢。 - Bazinga777
2
上下文意味着 this 将会在你的函数内引用不同的对象。 - dfsq

8
addEventListener()函数的第二个参数接受类型函数。因此,您不能传递initialiseMediaPlayer();,因为那是一个函数调用。
您可以这样做:
```javascript addEventListener('load', initialiseMediaPlayer); ```
var onDOMContentLoaded = function() {
    initialiseMediaPlayer();
};
document.addEventListener("DOMContentLoaded", onDOMContentLoaded, false);

谢谢,我也是这么想的。 - Bazinga777

0

在第一种情况下

document.addEventListener("DOMContentLoaded", function() {
    initialiseMediaPlayer();
}, false);

匿名函数function(){initialiseMediaPlayer();}被注册为在文档事件“DOMContentLoaded”触发时触发

第二种情况:

document.addEventListener("DOMContentLoaded", initialiseMediaPlayer();, false);

注册为事件监听器的是表达式 initialiseMediaPlayer() 的结果

所以,是的,有所不同 :)


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