script放在HTML哪裡比較好?
最近有在學習《Javascript DOM變成藝術》這本書,書上的很多案例在實際執行的時候沒有出現預定的結果,這些error給了我很多啟發,其中之一就是script在HTML擺放的位置。
長期以來,script在HTML中的位置對我而言就是一個詞:隨意。而這種隨意性有時又造成了一些匪夷所思的問題。比如今天執行showpic.js中的程式碼:
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++)
{
if(links[i].getAttribute("class") == "popUp")
{
links[i].onclick = function()
{
popUp(this.href);
return false;
}
}
}
Html:
<a href="http://www.osu.edu" class="popUp">click me</a>
其中我把script放在了<head>中。令人奇怪的現象發生了,本來應該是出現的彈窗,變成了href的直接顯示,而直接呼叫onClick = "popUp(this.href); return false;"卻又完全沒問題。而這兩者在邏輯中完全是等價的。這就有點讓人疑惑了。開啟chrome除錯,發現點連結是時候直接用的href,根本沒有用到script,原因何在?
通過查詢,在stackoverflow(強大的stackoverflow!)中找到了非常滿意的答案,大家可以看這個連結:http://stackoverflow.com/questions/436411/where-is-the-best-place-to-put-script-tags-in-html-markup。解釋一下就是:
當編譯器遇到script的時候,會停止對html的parse,直到script下載並且執行完了才會繼續parse html。因為我的script在head裡面,body之前,所以執行時根本就沒有任何html部件,也就談不上對部件的操作了。
那理想的解決方案是什麼呢?如果把script放在<body>的最後是不是就可以了呢?理論上來說完全是可以的,只是對於比較大型的網站,要等所有的html部件(有些部件比如圖片視訊載入是很慢的)都載入玩才能執行JS的話,客戶會等比較長的時間,造成比較差的使用者體驗。所有這個並不是完美的解決方案。
最完滿的解決方法是使用async和defer,像這樣:
<script type="text/javascript" src="script/showpic.js" async></script>
<script type="text/javascript" src="script/showpic.js" defer></script>
async代表在JS載入和執行的時候,Html會繼續載入,所以這樣子呼叫HTML的部件是沒有問題的(其實我不知道對部件比較多的時候可不可以,可能execute的時候想要的部件還沒有加載出來)。而defer和async不同就在於defer是在所有部件載入完之後才執行的。可以根據不同的需求來選擇這兩個屬性。
不過這個解決方案雖然堪稱完美,但是還有20%的瀏覽器是不支援這個功能的,所以還是酌情使用吧!(吐個槽,感覺做前端要考慮各種不同的瀏覽器真的蠻心累的,要是有個大一統的標準就好了~私心裡希望大Chrome一統天下哈哈,當然Safari也不錯,至於IE,請圓潤的離開吧...)