天天看點

透徹了解script标簽

最近我看了不少教材,發現談及在html檔案中使用JavaScript的時候,基本都是概括為2種方法:

  1. 内聯:在頁面處插入script标簽,其中JavaScript代碼寫在閉合标簽script之間,例如下面這樣:
<script>
	console.log("Hello World!");
</script>

           

2.利用script标簽的src屬性,從外部引入,例如下面這樣的:

<script src="myJavaScript.js"></script>
           

使用了src屬性的script标簽之間不能再在其中寫功能性代碼,因為浏覽器會加載src所指向的.js檔案的代碼,而不會執行标簽之間的代碼,也就是說,假設我們寫成下面這樣

//html檔案
<script src = “myJavaScript.js”>
	console.log("内聯的代碼")
</script>

//myJavaScript.js檔案
console.log("通過src引入的代碼")

最終顯示結果:内聯的代碼
           

上面就是在src标簽内的使用了src屬性,但是也在script标簽之間寫入了代碼,但是最終控制台列印出來的是src屬性引入的外部js檔案中的代碼。

在《JavaScript權威指南(第六版)》中,其實還提到了2種已經廢棄的(準确說基本很難見到的引入方式:html事件處理程式和URL中的JavaScript引入)

1.html事件處理程式比較好了解,簡單來說,就是通過事件的觸發來完成某種響應,在這裡,引入JavaScript代碼就是我們的響應,比如下面這段代碼:

<div onclick = " console.log('你點選了div')">
	點選這裡
</div>
           

使用者通過點選div,觸發了點選事件,想用的内容為列印出“你點選了div”字元串

2.URL後跟JavaScript:協定限定符

在html中,任何正常使用url的地方都可以用這種方法引入JavaScript代碼,比如a标簽的href,form标簽的action,比如下面這樣的:

<a href = "javascript:new Date().toLocalTimeString();">點選超連結</a>
           

點選後,浏覽器會擦去目前文檔并顯示新文檔**,

注意:

這裡是擦除整個文檔,而不是連結之間的文本内容。

以上的2種方法是web早期的使用,至今已經少有見到了,我們真正地還是使用script标簽的src屬性較多,因為,一來是外部引入src标簽很友善于後期的維護和代碼的重複使用,二來src屬性可以實作jsonp等跨域

是以接下來,我們還是來好好看看script标簽吧。

我們知道JavaScript是一門單線程的解釋性語言(從上至下一行一行地解讀代碼),當用戶端拿到文檔時,從html開始往下加載,當遇到script标簽時,浏覽器預設先執行js腳本,然後再恢複對文檔的解析和渲染。

這樣就很容易出現一個問題,就是當我們使用外部引入的腳本時,在這個腳本徹底解析完之前,這個腳本後面的文檔部分是不能被下載下傳的,也就是說,如果這個腳本恰好非常龐大,解析時間需要很長,那麼頁面可能會出現空白,也就是我們常說的阻塞

script标簽具備defer和async屬性,它們的使用有以下限制:

1.隻在外部腳本引入時有效

2.都是布爾屬性,沒有值

在不給script腳本添加defer或者async,我們的文檔正常解析順序是:

文檔結構的解析→遇到script→停下文檔的解析,開始加載script腳本檔案→開始執行腳本檔案→執行腳本檔案完畢,繼續後續的文檔的解析

即同步

而defer和async同時異步加載了腳本,不同的是,二者的不同主要展現在執行腳本階段,我用畫圖的方式說明:

透徹了解script标簽

對于腳本的加載,defer和async都會在背景開啟一個新的線程,但是,defer對于腳本執行,必須在文檔解析完成之後再進行,且是按照順序執行。而async對于腳本執行,則是在腳本加載完後執行,且誰先加載完誰先執行

繼續閱讀