JavaScript 編碼基礎


要在瀏覽器中執行 JavaScript,可在一個 HTML 檔案中撰寫 <script></script>,並於兩個標籤間撰寫 JavaScript 程式碼。例如:

<script>
    var name = prompt('輸入你的名稱');
    alert('哈囉! ' + name + '!');
</script>

按我執行範例

這個簡單的網頁會出現對話框,在當中輸入任意字元,即使輸入「王大犇」也可以正確在下一個警示方塊中顯示,這是因為 JavaScript 支援 Unicode(內部實作上採用 16 位元編碼每個字串元素,大致上可視為 UCS-2/UTF-16,這當中還有些歷史因素造成的細節,詳見《Effective JavaScript》條款七),輸入的接收或警示方塊的訊息顯示,都是以 Unicode 處理。

如果將 JavaScript 儲存於 .js 檔案中,並在 HTML 中如下載入 .js 檔案:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="js/JavaScript-2.js"></script>
    <meta charset="Big5">
  </head>
  <body>
  </body>
</html>

按我執行範例

在這邊要注意編碼的問題,瀏覽器會假設載入的 .js 編碼與 HTM L網頁編碼相同。如果 .js 檔案與 HTML 編碼不同,JavaScript 中非 ASCII 相容字元部份就會出現亂碼。例如,若 .js 如下:

alert('測試');

若這個 .js 檔案是 Big5 編碼,則會顯示:

JavaScript 編碼基礎

如果 .js 檔案是 UTF-8 編碼,則會顯示:

JavaScript 編碼基礎

如果 .js 是 UTF-8 編碼,而網頁是 Big5,可以在 <script> 上使用 charset 指定 .js 的編碼為 UTF-8:

<script type="text/javascript" charset="UTF-8" src="js/JavaScript-2.js"></script>

如此,瀏覽器才會知道以 UTF-8 載入 .js 檔案,才可以正確顯示中文,只要 JavaScript 程式中撰寫的字串,可以正確地被執行環境載入執行,那麼在操作 DOM 物件相關特性(Properties)時,就可以正確地顯示字串,無論原本的 HTML 網頁是什麼編碼。

舉例來說,若有個 UTF-8 的 .js 檔案:

window.onload = function() {
    var name = '王大犇';
    document.getElementById('input1').value = name;
    document.getElementById('span1').innerHTML = name;
};

雖然這當中的「犇」字,不是 Big5 範圍內的編碼,但 Big5 網頁中載入後:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" charset="UTF-8"
            src="js/JavaScript-3.js"></script>
    <meta charset="Big5">
  </head>
  <body>
     欄位:<input id="input1" type="text"><br>
     <span id="span1"></span>
  </body>
</html>

也是可以正確地顯示出「王大犇」:

JavaScript 編碼基礎

別以為可以這麼撰寫並將 HTML 檔案使用 Big5 儲存:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
        window.onload = function() {
            var name = '王大犇';
            document.getElementById('input1').value = name;
            document.getElementById('span1').innerHTML = name;
        };
    </script>
    <meta charset="Big5">
  </head>
  <body>
     欄位:<input id="input1" type="text"><br>
     <span id="span1"></span>
  </body>
</html>

無論編輯器是否會對「犇」字提出無法以 Big5 儲存的警告,就算編輯器無聲無息地儲存了檔案,實際上原始碼已經是:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
        window.onload = function() {
            var name = '王大?';
            document.getElementById('input1').value = name;
            document.getElementById('span1').innerHTML = name;
        };
    </script>
    <meta charset="Big5">
  </head>
  <body>
     欄位:<input id="input1" type="text"><br>
     <span id="span1"></span>
  </body>
</html>

在〈Big 5 網頁難字〉中談過,可以在 HTML 中使用實體編號來解決 Big5 難字問題,也許你會想到這麼撰寫:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
        window.onload = function() {
            var name = '&#29319';
            document.getElementById('input1').value = name;
            document.getElementById('span1').innerHTML = name;
        };
    </script>
    <meta charset="Big5">
  </head>
  <body>
     欄位:<input id="input1" type="text"><br>
     <span id="span1"></span>
  </body>
</html>

不過這會使得瀏覽器如下顯示:

JavaScript 編碼基礎

innerHTML 特性是個較特別的特性,指定給它的字串會被當作 HTML 進行剖析,但其它 DOM 特性就不會將字串視為 HTML 了,很可惜地,JavaScript 的核心 API 中,String 也沒有 escapeHTMLunescapeHTML() 之類的方法。

一個投機的方式,就是從 innerHTML 下手,既然傳給 innerHTML 的字串被當作 HTML 解釋了,而且也正確顯示出字元了,這表示在 JavaScript 執行環境中,它已經是個正確地 Unicode 字串了,那就從 innerHTML 再取回字串:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
        window.onload = function() {
            var name = '&#29319';
            document.getElementById('span1').innerHTML = name;
            document.getElementById('input1').value = 
                   document.getElementById('span1').innerHTML;
            alert(document.getElementById('input1').value);
        };
    </script>
    <meta charset="Big5">
  </head>
  <body>
     欄位:<input id="input1" type="text"><br>
     <span id="span1"></span>
  </body>
</html>

按我執行範例

這個程式還順便從輸入欄位取得最後的字串結果,結果也是顯示正確的字元:

JavaScript 編碼基礎

只要能正確在瀏覽器中顯示字元,透過 DOM 特性取得的就會是正確的字元,無論是哪種網頁編碼。