要在瀏覽器中執行 JavaScript,可在一個 HTML 檔案中撰寫 <script></script>
,並於兩個標籤間撰寫 JavaScript 程式碼。例如:
<script>
let name = prompt('Input your name');
alert(`Hello! ${name}!`);
</script>
上例中,prompt
與 alert
是瀏覽器上全域物件上提供的函式,在瀏覽器中,全域物件就是 window
物件,代表瀏覽器本身,為 Window
的實例。當然,上面的 JavaScript 程式沒什麼作用,只是讓你輸入名稱並顯示而已。你可以將 <script></script>
放在 HTML 標籤之中。例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
JavaScript Example!<br>
<script>
let name = prompt('Input your name');
document.write(`Hello! ${name}!`);
</script><br>
JavaScript Example!
</body>
</html>
預設情況下,瀏覽器在遇到 <script></script>
時,會停止文件解析,先執行 <script></script>
間的JavaScript,document
是 window
全域物件上的特性,代表整份 HTML 文件,為 Document
的實例。如果執行 document
的 write()
方法,則會在 <body>
中目前文件解析點輸出指定的文字,執行完 <script></script>
間的 JavaScript 後,再繼續文件的解析。
基本上,瀏覽器會假設你使用的是 JavaScrip t語言,不過也可以用 HTTP Content-Script-Type
標頭來指定,標頭可以使用 <meta>
來摸擬,所以可以如下指定:
<meta http-equiv="Content-Script-Type" content="text/javascript">
也可以在 <script>
上使用 type
屬性來指定。例如:
<script type="text/javascript">
// 你的程式碼
</script>
type
指定可以是 MIME(Multipurpose Internet Mail Extension)型態,一些可指定的範例有:
text/javascript
text/ecmascript
application/javascript
text/jscript
text/vbscript
- …
第一個是 JavaScript 的官方名稱,其它類型的指定,主要是看瀏覽器是否支援,例如在安裝 IronPython 的情況下,甚至可以讓 Internet Explorer 支援 text/python
的指定。
HTML4 規範了 type
屬性,但在 HTML5 中為選用。在早期,<script>
上還允許設定 language
屬性,在 HTML 4 時標準化 <script>
標籤時,並沒有採納 language
屬性,有時會有一些早期撰寫的網頁上看到這樣的設定:
<script language="javascript">
// 你的程式碼
</script>
language
甚至也允許撰寫版本號,例如:
<script language="javascript1.2">
// 你的程式碼
</script>
由於 HTML 4 並沒有採納 language
,現在已不建議設定,新版瀏覽器也會忽略這個屬性,僅有時為了與舊版瀏覽器相容,你會看到這樣的設定:
<script type="text/javascript" language="javascript">
// 你的程式碼
</script>
可以將 <script></script>
放在整份 HTML 文件之後,</body>
之前,依照現在的最佳實踐來說,應該這麼做,因為 HTML 文件此時已經載入、剖析完成,應有的 DOM 元素也已經產生,若 JavaScript 必須操作 DOM 元素,此時可以放心地進行操作。
也可以將 <script></script>
放在 <head></head>
之間,過去瀏覽器上的 JavaScript 程式碼,經常是這麼做的。例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script type="text/javascript">
let name = prompt('Input your name');
document.write(`Hello! ${name}`);
</script>
</head>
<body>
JavaScript Example!
</body>
</html>
要注意的是,瀏覽器處理 <head></head>
間的JavaScript時,還沒有解析 <body>
中的標籤,所以上例中,document
的 write
會直接從 <body>
的第一行開始。一般初學者常犯的錯誤是:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script type="text/javascript">
let welcome = document.getElementById('welcome');
welcome.innerHTML = `Hello! ${prompt('Input your name')}!`;
</script>
</head>
<body>
<span id="welcome"></span>
</body>
</html>
document
的 getElementById
可以根據 HTML 標籤的 id
屬性值取得 HTML 標籤的 DOM 物件,innerHTML
可設定實例的 HTML 內容(innerHTML
在 HTML5 中是標準特性)。在執行上例的 JavaScript 時,<body></body>
中的文件根本還沒開始解析,所以 <span id="welcome"></span>
根本還不存在,所以取得的是 undefined
,根本無從設定 innerHTML
,若是將上例中的 <script>
程式碼移至 </body>
之前,就不會有這個問題。
要等到全部文件資源完整載入後再執行指定的程式碼,也可以借助 window.onload
事件。例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script type="text/javascript">
window.onload = function() {
let welcome = document.getElementById('welcome');
welcome.innerHTML = `Hello! ${prompt('Input your name')}!`;
};
</script>
</head>
<body>
<span id="welcome"></span>
</body>
</html>
window
物件的 onload
特性可以指定函式,當瀏覽器完成整份文件資源的載入後,如果 onload
特性有設定函式,就會予以呼叫,然而,完成整份文件資源的載入是指 HTML、CSS、圖片等都被載入完成,而不是單指是 DOM 樹建立完成,因此,如果文件資源非常的多,或者是網路速度不佳,那麼在可以執行 JavaScript 的效果之前,訪客看到的可能會是不完整的使用者介面。
可以將 JavaScript 程式撰寫在 .js 檔案中,並使用 <script>
的 src
屬性指定檔案名稱。例如,將底下的程式寫在一個 hello.js:
window.onload = function() {
let welcome = document.getElementById('welcome');
welcome.innerHTML = `Hello! ${prompt('Input your name')}!`;
};
如果上面的 .js 檔案放在 js 資料夾中,則可以如下使用:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script type="text/javascript" src="js/hello.js"></script>
</head>
<body>
<span id="welcome"></span>
</body>
</html>
按此看執行結果(在 JS Bin 中,只要寫在 JavaScript 頁框中的程式碼,會自動嵌入 HTML 之中)。
雖然程式都在 .js 中,但 <script></script>
還是要成對出現,而 <script></script>
中出現的程式碼會被忽略。
在這邊要注意編碼的問題,瀏覽器會假設載入的 .js 檔案編碼與 HTML 網頁編碼相同。如果 .js 檔案編碼與 HTML 編碼不同,JavaScript 中非 ASCII 相容字元部份就會出現亂碼。
例如,如果 .js 是 Big5 編碼,而網頁是 UTF-8 顯示,則可以在 <script>
上使用 charset
指定 .js
的編碼為 Big5:
<script type="text/javascript" charset="Big5" src="js/hello.js"></script>
預設情況下,瀏覽器會同步地下載 .js 檔案,直到 .js 下載完成,並執行完內容之前,後續的其他資源下載、頁面剖析等都會被阻斷。
可以在 <script>
加上 async
屬性,如此瀏覽器會以非同步方式下載 .js 檔案,在 .js 下載完成前,不會阻斷後續資源的下載與頁面剖析,然而 .js 下載完成後,瀏覽器會暫停其他資源下載或頁面剖析,先執行該 .js 的內容後,再繼續處理其他資源下載或頁面剖析,如果有多個 async
屬性的 .js,執行的順序是無法預期的。
可以在 <script>
加上 defer
屬性,如此瀏覽器會以非同步方式下載 .js 檔案,.js 就算下載完成,也不會馬上執行,而是在 DOM 樹生成與其他非 defer
的 .js 執行完後,才執行被加上 defer
屬性的 .js,如果有多個 defer
屬性的 .js,那麼按照它們在頁面上出現的順序執行。
現在不支援 JavaScript 的瀏覽器幾不存在,不過瀏覽器上的 JavaScript 仍可能因一些原因無法使用(例如防毒軟體、安全機制等級,或者是爬蟲程式之類)。如果想在無法執行 JavaScript 時,仍可呈現一些基本功能畫面,則可以使用 <noscript></noscript>
,夾雜在 <noscript></noscript>
中的內容,會在無法執行 JavaScript 時出現,為使用者提供替代的頁面內容。
有些瀏覽器或爬蟲無法執行 JavaScript,此時會使用 <!--
與 -->
註解,讓這些它們看不到 JavaScript 程式碼:
<script type="text/javascript">
<!--
// 你的程式...
//-->
</script>
瀏覽器作為客戶端的時候作了些調整,讓 <!--
的作用如同 JavaScript 的 //
單行註解,所以 <!--
不會發生執行錯誤,而 -->
前的 //
因為是單行註解,所以就看不到之後的 -->
了。