(續(xù)···)
? ? ? ?與解析嵌入式JavaScript 代碼一樣,在解析外部JavaScript文件(包括下載文件)時,頁面的處理也會暫時停止。
? ? ? ?按照慣例,外部JavaScript文件帶有.js擴(kuò)展名。但這個擴(kuò)展名不是必須的,因為瀏覽器不會檢查包含JavaScript的文章的擴(kuò)展名。這樣一來,使用 JSP、 PHP 或其他服務(wù)器端語言動態(tài)生成 JavaScript 代碼也就成為了可能。但是,服務(wù)器通常還是需要看擴(kuò)展名決定為響應(yīng)應(yīng)用哪種 MIME 類型。如果不使用.js 擴(kuò)展名,請確保服務(wù)器能返回正確的 MIME 類型。
Note :
1. 帶有src屬性的元素不應(yīng)該在其和標(biāo)簽之間再包含額外的JavaScript代碼,如果包含了嵌入的代碼,則只會下載和執(zhí)行外部文件的JavaScript代碼,嵌入的代碼將會被忽略。
2. ?另外,通過<script>元素的src屬性還可以包含來自外部域的JavaScript文件。這一點既讓<script>元素倍顯強大,也讓它備受爭議。這一點上,<script>元素和<img>非常相似,即它的src 可以指向當(dāng)前HTML所在域之外的某個域的完整url。在訪問自己不能控制的服務(wù)器上的JavaScript 文件要多加小心。元素的src屬性還可以包含來自外部域的JavaScript文件。這一點既讓元素的src屬性還可以包含來自外部域的JavaScript文件。這一點既讓
3. 無論如何包含代碼,只要不存在 defer 和 async 屬性,瀏覽器都會按照<script>元素所在的前后順序依次進(jìn)行解析
2.1.1標(biāo)簽的位置
1,傳統(tǒng)做法:
所有<script>元素都應(yīng)該放在頁面的<head>元素中。
這樣做的目的是所有外部文件(包括css文件和JavaScript文件)的引用都放在相同的地方。這意味著必須等到所有的JavaScript文件被下載,解析和執(zhí)行完成以后,才能開始呈現(xiàn)頁面(瀏覽器在遇到<body>標(biāo)簽時才開始呈現(xiàn)內(nèi)容)。 這樣就導(dǎo)致瀏覽器在呈現(xiàn)那些需要很多JavaScript代碼的頁面時出現(xiàn)明顯的延遲。而延遲期間的瀏覽器窗口中將是一片空白
2,現(xiàn)代WEB應(yīng)用程序
一般都把全部的JavaScript引用放在<body>元素中頁面內(nèi)容的后面。
在解析包含的JavaScript代碼之前,頁面的內(nèi)容將完全呈現(xiàn)在瀏覽器中。而用戶也會因為瀏覽器窗口顯示空白頁面的時間縮短而感到打開頁面的速度加快了。
2.1.2延遲腳本
HTML4.01 為JavaScript定義了 defer 屬性。腳本會被延遲到整個頁面都解析完畢后再運行。
在<script>元素中設(shè)置defer屬性,相當(dāng)于告訴瀏覽器 立即下載但是延遲執(zhí)行。
<html>
?<head>
? <script type="text/javascript" defer="defer" src="example.js"></script>
?</head>
?<body>
?</body>
</html>
雖然我們把<script>元素放在文檔<head>元素中,但其中包含的腳本將延遲到瀏覽器遇到</html>標(biāo)簽后再執(zhí)行。
HTML5規(guī)范要求腳本按照它們出現(xiàn)的先后順序執(zhí)行,因此第一個延遲腳本會先于第二個延遲腳本執(zhí)行,而這兩個腳本會先于DOMContentLoaded事件 (詳見第13章)執(zhí)行。在現(xiàn)實當(dāng)中,延遲腳本并不一定會按照順序執(zhí)行,也不一定會在DOMContentLoaded事件觸發(fā)前執(zhí)行,因此最好只包含一個延遲腳本。
defer屬性只適用于外部腳本文件,把延遲腳本放在頁面底部仍然是最佳選擇。
2.1.3 異步腳本
HTML5為<script>元素定義了async屬性。這個屬性和defer屬性類似,都用于改變處理腳本的行為。
同樣與 defer 類似, async 只適用于外部腳本文件,并告訴瀏覽器立即下載文件。但與 defer不同的是,標(biāo)記為 async 的腳本并不保證按照指定它們的先后順序執(zhí)行。
<html>
?<head>
? ?<script type="text/javascript" async src="example1.js"></script>
? ?<script type="text/javascript" async src="example2.js"></script>
?</head>
?<body>
?</body>
</html>
在以上代碼中,第二個腳本文件可能會在第一個腳本文件之前執(zhí)行。因此,確保兩者之間互不依賴非常重要。
指定async屬性的目的是不讓頁面等待兩個腳本下載和執(zhí)行,從而異步加載頁面其他內(nèi)容。為此,建議異步腳本不要在加載期間修改DOM。
異步腳本一定會在頁面的load事件前執(zhí)行,但可能會在DOMContentLoaded事件觸發(fā)之前或之后執(zhí)行。支持異步腳本的瀏覽器有Firefox 3.6、Safari 5和Chrome。
2.2 嵌入代碼和外部文件
在HTML中嵌入JavaScript代碼雖然沒有問題,但一般認(rèn)為最好的做法還是盡可能使用外部文件來包含JavaScript代碼。
外部文件優(yōu)點:
1,可維護(hù)性(遍及不同HTML頁面的JavaScript會造成維護(hù)問題。但把所有JavaScript文件都放在一個文件夾中,維護(hù)起來就輕松多了。);
2,可緩存(瀏覽器能夠根據(jù)具體的設(shè)置緩存鏈接的所有外部JavaScript文件。);
3,適應(yīng)未來(HTML和XHTML包含外部文件的語法是相同的。);
2.3 文檔模式
IE5.5引入了文檔模式的概念,而這個概念是通過使用文檔類型(doctype)切換實現(xiàn)的。最初的兩種文檔模式是:混雜模式(quirks mode)和標(biāo)準(zhǔn)模式(standards mode)。混雜模式會讓IE的行為與(包含非標(biāo)準(zhǔn)特性的)IE5相同,而標(biāo)準(zhǔn)模式則讓IE的行為更接近標(biāo)準(zhǔn)行為。雖然這兩種模式主要影響CSS內(nèi)容的呈現(xiàn),但在某些情況下也會影響到JavaScript的解釋執(zhí)行。
在此之后,IE又提出一種所謂的準(zhǔn)標(biāo)準(zhǔn)模式(almost standards mode)。
準(zhǔn)標(biāo)準(zhǔn)模式與標(biāo)準(zhǔn)模式非常接近,它們的差異幾乎可以忽略不計。因此,當(dāng)有人提到“標(biāo)準(zhǔn)模式”時,有可能是指這兩種模式中的任何一種。
2.4 <noscript>元素
用以在不支持JavaScript的瀏覽器中顯示替代的內(nèi)容。這個元素可以包含能夠出現(xiàn)在文檔<body>中的任何HTML元素——<script>元素除外。
包含在<noscript>元素中的內(nèi)容只有在下列情況下才會顯示出來
?瀏覽器不支持腳本;
?瀏覽器支持腳本,但腳本被禁用。
符合上述任何一個條件,瀏覽器都會顯示<noscript>中的內(nèi)容,在除此之外的其他情況瀏覽器不會呈現(xiàn)<noscript>中的內(nèi)容。
<html>
?<head>
? <script type="text/javascript" defer="defer" src="example.js"></script>
?</head>
?<body>
? <noscript>
? ? <p>本頁面需要瀏覽器支持(啟用)JavaScript</p>
? <noscript>
?</body>
</html>
這個頁面會在腳本無效的情況下向用戶顯示一條消息。而在啟用了腳本的瀏覽器中,用戶永遠(yuǎn)也不會看到它——盡管它是頁面的一部分。