2012-05-27 69 views
5

这个问题是如此基本,我肯定在东西,即使我已经looked for something similar重复。Javascript:最好的地方注册事件处理程序

我的问题基本上是:最初为HTML元素注册事件处理程序的最佳位置在哪里

注册的事件处理程序最简单的办法显然是只是做内联:

<div id = "mybutton" onclick = "doSomething()">Click me</div> 

但这就违背了朝现代网络的发展逻辑和内容分离压倒性的游行。因此,在2012年,所有的逻辑/行为都应该在纯Javascript代码中完成。这很好,并且会导致更多可维护的代码。但你仍然需要一些初始的钩子,用你的Javascript代码来连接你的HTML元素。

通常情况下,我只是这样做:

<body onload = "registerAllEventHandlers()"> 

不过...。那仍是“欺骗”,是不是 - 因为我们仍然使用内嵌的JavaScript在这里。但我们还有其他的选择吗?我们不能做到这一点在<head>节一<script>标签,因为在这一点上,我们不能访问DOM,因为在页面尚未加载:

<head> 
<script type = "text/javascript"> 
    var myButton = document.getElementById("mybutton"); // myButton is null! 
</script> 
</head> 

难道我们放置<script>标签在底部的网页或东西?像:

<html> 
<body> 
... 
... 
<script type = "text/javascript"> 
    registerAllEventHandlers(); 
</script> 
</body> 
</html> 

这里的最佳做法是什么?

回答

2

您可以使用window.onload

<script type = "text/javascript"> 
    window.onload = registerAllEventHandlers; 
</script> 

或者,如果你使用

$(registerAllEventHandlers); 

使用onload的作品,因为它立即注册onload事件,但触发它时,DOM已准备就绪。

+0

-1:'window.onload'事件不等同于使用jQuery的'ready'事件:'window.onload'将在页面加载完成时触发,包括所有外部资源(图像,CSS等)在HTML完成加载之后但在外部资源之前,jQuery的'ready'事件将触发。使用'window.onload'是一个坏主意,因为在很多情况下(很多图像,连接速度慢等),JavaScript事件很长一段时间不会被注册。 – georgebrock

+0

@slebetman:你能否详细说明为什么在加载图像(等)之前附加JS事件处理程序是愚蠢的,并且理解两种不同技术之间的区别?在一个旨在学习和分享信息的网站上,评论说“这很愚蠢”并不是很有建设性。 – georgebrock

0

我有a similar answer这个,但一般是关于JavaScript。但这个想法仍然是一样的 - 在关闭主体之前加载脚本。

利用抽象了window.onload和DOM就绪事件的库。这样,只要DOM准备好就可以加载脚本。

0

只要DOM准备就绪,您应该注册您的事件处理程序。在所有浏览器中检测到这一点并不总是那么容易,但除了IE 8(及更早版本)之外,最广泛使用的浏览器现在支持DOMContentLoaded事件(感谢gengkev在注释中指出)。

这实际上相当于在body的末尾调用registerAllEventHandlers函数,但它的优点是不需要向HTML中添加任何JavaScript。

它比使用window.onload好得多,因为直到页面的所有资源(图像,CSS等)都被加载后才会执行该操作。

如果您使用的是一个主要的JavaScript框架,那么即使在旧版本的IE中,您也可以非常轻松地检测DOM何时准备就绪。随着jQuery的你可以使用ready event

jQuery(document).ready(function() { 
    // Your initialisation code here 
}); 

或者简写:

jQuery(function() { … }); 

原型你可以使用dom:loaded event

document.observe("dom:loaded", function() { 
    // Your initialisation code here 
}); 
+1

DOMContentLoaded在几乎所有的浏览器中,但IE <9 – gengkev

+0

我不知道现在是如此广泛的支持,我想我已经习惯了让jQuery来帮助我。谢谢@gengkev – georgebrock

0

就个人而言,我没有向元素添加onlclick="doSomething();"时遇到问题秒。没有逻辑,只是一个函数调用。

所有逻辑都应该是:在HEAD中定义的函数或单独的文件中。

告诉我,将href="somepage.html"甚至href="somepage.html#someanchor"添加到A标记时有何区别。

+0

我很少发现我只有一个需要一些行为的链接;通常它是一组类似的链接。当该行为发生变化或不再需要时,我发现更改或删除一个定义行为并将其附加到相关链接的'.js'文件更方便,而不是更改或删除许多onclick属性很多链接。 – georgebrock

+0

@georgebrock如果你想重命名/重新构造你的HTML文件,你可以这么说 - 你仍然需要去每个'A'标签并改变'href'属性。无论如何,在你的情况下,不需要改变函数名称,只需重新编写函数。如果onclick的行为正在改变,那么也许值得将函数名改为别的。不过你说得很好。 – Matthew

+0

一旦一个网站在公共网络上,更改'href'属性将是一件头痛的事情,因为[很酷的URIs不会改变](http://www.w3.org/Provider/Style/URI) (当他们必须改变时,他们应该301到新的位置)。但我离题了。既然你可以编写你的JavaScript,以便有一个单一的变化点和明确的问题分离,为什么不这样做呢? – georgebrock

相关问题