說一說 HTML 中的 script 標籤

Modeng發表於2019-02-16

我們在 《Javascript簡史》這遍文章中說過,「Javascript」這門語言是由 Netscape開發而來,當初開發的時候為了能讓 「Javascript」這門語言能與 HTML 頁面共存,而且不影響頁面的其他內容,為此增加了一個統一的指令碼支援( script 指令碼元素)。

script 元素

在 HTML 頁面中使用「Javascript」語言主要的方法就是使用 script 元素,script 元素內部的程式碼從上而下依次執行。

在引入多個 script 元素的時候,瀏覽器會按照 script 元素在頁面的中的先後順序進行解析,當上一個解析完成時,才會進行下一個 script 元素中的內容

在 HTML 中使用 Javascript 的兩種方法

//第一種方法:直接在標籤內使用 javascript 即可
<script>
    console.log(`第一種使用方法`);
</script>

//第二種方法:引用外部檔案
<script src="example.js"></script>

script 元素的屬性

script 元素比較常用的幾個屬性

  • src:可選,用於引用外部 javascript 檔案
  • type:可選,編寫程式碼使用的指令碼語言的型別(也成MIME型別),預設值為 text/javascript
  • async:可選,非同步載入指令碼,只對外部指令碼檔案有效
  • defer:可選,延遲指令碼載入,在文件完全被解析後在執行,只對外部指令碼檔案有效

script 元素在 HTML 中的位置

由於「Javascript」語言是一門單執行緒語言,在同一時間內,只能執行一個任務,所以只有當上一個任務完成之後才能進行下一個任務,因此會導致 script 元素在 HTML 中的位置不同,會表現出不同效果。

所有 script 元素都放在 <head> 元素中

這種做法意味著,我們必須等待所有的 Javascript 程式碼必須執行完成之後才能開始展示頁面的內容,如果頁面的 Javascript 程式碼非常多,這種方法就會導致我們看到頁面的載入會非常慢,使用者體驗非常差,那麼這麼樣去優化呢?其實很簡單。

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <script src="example1.js"></script>
        <script src="example2.js"></script>
    </head>
    <body>
        <div>頁面的內容區域</div>
    </body>
</html>

所有 script 元素都放在頁面內容的後面

優化上面所說的頁面載入慢的問題,只需要把我們使用的 Javascript 程式碼放到頁面的內容之後即可,這樣頁面會首先載入內容然後現實出來,再去執行 Javascript 程式碼,這樣使用者就不會等待很久頁面才會顯示內容。

<!DOCTYPE html>
<html>
    <head>
        <title></title>
    </head>
    <body>
        <div>頁面的內容區域</div>
        <script src="example1.js"></script>
        <script src="example2.js"></script>
    </body>
</html>

指令碼的延時載入

指令碼如何進行延時載入,這個就要利用 script 元素的 defer 屬性,在元素使用 defer 屬性時,指令碼會被延遲到整個頁面解析完成後在執行。

//example1.js 中的程式碼
//console.log(`example1`);
//console.log(document.getElementById(`content`));

//example2.js 中的程式碼
//console.log(`example2`);
//console.log(document.getElementById(`content`));

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script defer src="example1.js"></script>
    <script defer src="example2.js"></script>
</head>
<body>
    <div id="content">這裡頁面的內容</div>
</body>
</html>

你會發在沒有加入 defer 屬性時控制檯會列印出如下結果

example1
null
example2
null

當給元素加上 defer 屬性時,結果會發生變化,可以發現在 div 元素的內容載入完成之後 Javascript 程式碼才會執行。

example1
<div id="content">這裡頁面的內容</div>
example2
<div id="content">這裡頁面的內容</div>

指令碼的非同步載入

指令碼的非同步載入,要用到 script 元素到 async 屬性,它與 defer 屬性類似,都是修改 script 元素的載入行為,不過 async 屬性不會影響頁面的其他載入,不會阻塞文件呈現,而且帶有 async 屬性的指令碼不能保證它們執行的前後順序,這一點與 defer 屬性有著不同之處。

換句話說 example2.js 的程式碼可能會先於 example1.js 中的程式碼執行,所以在使用 async 屬性時,要避免兩個 js 相互依賴。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script async src="example1.js"></script>
    <script async src="example2.js"></script>
</head>
<body>
    <div id="content">這裡頁面的內容</div>
</body>
</html>

noscript 元素

早期的瀏覽器都會又一個問題,那就是當瀏覽器不支援 Javascript 語言時如何顯示頁面內容,為此的解決方案就是建立了一個 noscript 元素,它可以在不支援 Javascript 的瀏覽器中顯示內容,而且只會在不支援 Javascript 的瀏覽器中才會顯示其中的內容。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script async src="example1.js"></script>
    <script async src="example2.js"></script>
</head>
<body>
    <noscript>
        當前瀏覽器不支援 Javascript 請更換瀏覽器
    </noscript>
</body>
</html>

相關文章