2012-05-27 115 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

相關問題