在前面幾章中,學(xué)習(xí)了 JavaScript 的核心 ECMAScript 以及該語言工作方式的基礎(chǔ)知識(shí)。從本章開始,重點(diǎn)將轉(zhuǎn)移到如何在 Web 瀏覽器中使用 JavaScript 。
自 Netscape Navigator 2.0 初次引入 JavaScript 以來, Web 瀏覽器已有了長足的發(fā)展。今天的瀏覽器不再只能處理傳統(tǒng)的 HTML 文件,它們能處理各種格式的文件。具有諷刺意味的是,這些文件中的大多數(shù)都采用 JavaScript 作為動(dòng)態(tài)改變客戶端內(nèi)容的方式。這一章探討如何把 JavaScript 嵌入 HTML 及其他語言,并介紹了 BOM (瀏覽器對(duì)象模型)的一些基本概念。
5.1 HTML 中的 JavaScript
當(dāng)然,第一個(gè)利用嵌入式 JavaScript 的語言還是 HTML ,因此首先討論的自然是如何在 HTML 中使用 JavaScript 。 HTML 中嵌入 JavaScript 是從引入用于 JavaScript 的標(biāo)簽和為 HTML 的一些通用 部分增加了新特性開始的。
HTML 頁面中包含 JavaScript 使用 <script/> 標(biāo)簽實(shí)現(xiàn)的。該標(biāo)簽通常放置在頁面的 <head/> 標(biāo)簽中,最初定義的 <script/> 標(biāo)簽具有一個(gè)或兩個(gè)特性, language 特性聲明要使用的腳本語言, src 特性是可選的,聲明要加入頁面的外部 JavaScript 文件。 language 特性一般被設(shè)置為 JavaScript ,不過也可用它聲明 JavaScript 的確切版本,如 JavaScript 1.3 (如果省略 language 特性,瀏覽器默認(rèn)使用最新的 JavaScript 版本)。
盡管 <script/> 最初是為 JavaScript 設(shè)計(jì)的,但可以用于聲明任意多種不同的客戶端腳本語言, language 特性用于聲明使用的代碼的類型。例如,可把 language 特性設(shè)置為 VBScript ,使用 IE 的 VBScript 語言(只適用于 Windows )。
如果未聲明 src 特性,在 <script/> 中即可以任意形式編寫 JavaScript 代碼。如聲明了 src 特性,那么 <script/> 中的代碼可能就是無效的(由瀏覽器決定)。例如:
這個(gè)例子中既有內(nèi)嵌的 JavaScript 代碼,又有對(duì)外部 JavaScript 文件的鏈接。使用 src 特性,即可像引用圖像和樣式表一樣引用 JavaScript 文件。
雖然大多數(shù)瀏覽器并未要求,但根據(jù)規(guī)約,外部 JavaScript 文件的擴(kuò)展名應(yīng)為 .js (這樣可以使用 JSP 、 PHP 或其他服務(wù)器端的腳本語言動(dòng)態(tài)生成 JavaScript 代碼)。
外部 JavaScript 語言的格式非常簡單。事實(shí)上,它們只包含 JavaScript 代碼的純文本文件。在外部文件中不需要 <script/> 標(biāo)簽,引用文件的 <script/> 標(biāo)簽出現(xiàn)在 HTML 頁中。這使得外部 JavaScript 文件看起來很像其他程序設(shè)計(jì)語言的源代碼文件。
例如,考慮下面的內(nèi)嵌代碼:
要把函數(shù) sayHi() 放在外部文件 external.js 中,需要復(fù)制函數(shù)文本自身(如圖 5-1 所示)。
圖 5-1
然后可更新 HTML 代碼,加入這個(gè)外部文件:
對(duì)于 JavaScript 源文件中可加入哪些代碼并無規(guī)定,這意味著可以給 JavaScript 文件加入任意多個(gè)類定義、函數(shù),等等。
何時(shí)應(yīng)該采用內(nèi)嵌代碼,何時(shí)采用外部文件呢?雖然關(guān)于這一點(diǎn)并無確定而且簡潔的規(guī)則可循,不過一般認(rèn)為,大量的 JavaScript 代碼不應(yīng)內(nèi)嵌在 HTML 文件中,原因如下:
q 全性 ——只要查看頁面的源代碼,任何人都可確切地知道其中的代碼做了什么。如果懷有惡意的開發(fā)者查看了源代碼,就可能發(fā)現(xiàn)安全漏洞,危及整個(gè)站點(diǎn)或應(yīng)用程序的安全。此外,在外部文件中還可加入版權(quán)和其他知識(shí)產(chǎn)權(quán)通告,而不打斷頁面流。
q 代碼維護(hù) ——如果 JavaScript 代碼散布于多個(gè)頁面,那么代碼維護(hù)將變成一場惡夢(mèng)。把所有 JavaScript 文件放在一個(gè)目錄中要容易得多,這樣在發(fā)生 JavaScript 錯(cuò)誤時(shí),就不會(huì)對(duì)放置代碼的位置有任何疑問。
q 緩存 ——瀏覽器會(huì)根據(jù)特定的設(shè)置緩存所有外部鏈接的 JavaScript 文件,這意味著如果兩個(gè)頁面使用同一個(gè)文件,只需要下載該文件一次。這將加快下載速度。把同一段代碼放在多個(gè)頁面中,不止浪費(fèi),還增加了頁面大小,從而增加下載時(shí)間。
一般說來,所有代碼和函數(shù)的定義都在 HTML 頁的 <head/> 標(biāo)簽中,這樣在顯示頁面主體后,代碼就被完全裝載進(jìn)瀏覽器,可供使用了。唯一該出現(xiàn)在 <body/> 標(biāo)簽中的是調(diào)用前面定義的函數(shù)的代碼。
<script/> 放在 <body/> 內(nèi)時(shí),只要腳本所屬的那部分頁面被載入瀏覽器,腳本就會(huì)被執(zhí)行。這樣在載入整個(gè)頁面之前,也可執(zhí)行 JavaScript 代碼。例如:
在這段代碼中,方法 sayHi() 在頁面顯示所有文本前調(diào)用,這意味著警告消息將在文本 "This is the first text the user will see." 顯示前彈出。建議不采用這種在頁面的 <body/> 標(biāo)簽內(nèi)調(diào)用 JavaScript 函數(shù)的方法,應(yīng)該盡量避免它。相反的,建議在頁面主體中只使用 事件處理函數(shù) ( event handler ),例如:
這里,使用 <input/> 標(biāo)簽創(chuàng)建一個(gè)按鈕,點(diǎn)擊它時(shí)調(diào)用 sayHi() 方法。 onclick 特性聲明一個(gè)事件處理函數(shù),即響應(yīng)特定事件的代碼。第 9 章將詳細(xì)討論事件和事件處理函數(shù)。
注意,開始載入頁面時(shí), JavaScript 就開始運(yùn)行了,因此有可能調(diào)用尚未存在的函數(shù)。在前面的例子中,把原來的 <script/> 標(biāo)簽放在函數(shù)調(diào)用后就會(huì)引發(fā)錯(cuò)誤:
這個(gè)例子將引發(fā)錯(cuò)誤,因?yàn)樵诙x sayHi() 之前就調(diào)用了它。由于 JavaScript 是從上到下載入的,所以在遇到第二個(gè) <script/> 標(biāo)簽前,函數(shù) sayHi() 還不存在。注意這種問題,此外,如前所述,使用事件和事件處理函數(shù)調(diào)用 JavaScript 函數(shù)。
初次引入 JavaScript 時(shí),只有一種瀏覽器支持它,因此大家開始關(guān)心,不支持 JavaScript 的瀏覽器如何處理 <script/> 標(biāo)簽及其中包含的代碼。最后,設(shè)計(jì)了一種用于對(duì)舊的瀏覽器隱藏 JavaScri pt 代碼(這是一個(gè)短語,在當(dāng)今因特網(wǎng)上的許多 Web 站點(diǎn)的源代碼中都能找到它)的格式。下面的代碼在內(nèi)嵌代碼周圍加入 HTML 注釋,這樣其他瀏覽器就不會(huì)在屏幕上顯示這段代碼。
第一行緊接起始標(biāo)簽 <script> 開始一條 HTML 注釋。這樣做是有效的,因?yàn)闉g覽器仍然把該行余下的部分看成 HTML 的一部分, JavaScript 代碼從下一行開始。接下來的是常規(guī)的函數(shù)定義。第 2 行到最后一行是最有趣的部分,因?yàn)樗詥涡? JavaScript 注釋標(biāo)記(兩個(gè)前斜線)開始,后面是 HTML 注釋的結(jié)尾標(biāo)記( --> )。這一行仍被看作 JavaScript 代碼,所以單行注釋標(biāo)記是避免語法錯(cuò)所必需的。不過,舊的瀏覽器只承認(rèn) HMLT 注釋的結(jié)束標(biāo)記,因此,將忽略所有 JavaScript 代碼。但是,支持 JavaScript 的瀏覽器只忽略該行,繼續(xù)執(zhí)行 </script> 標(biāo)簽。
盡管這種隱藏代碼的方法在 Web 早期非常流行,今天卻不再是必需的。目前,大多數(shù) Web 瀏覽器都支持 JavaScript ,而不支持 JavaScript 的瀏覽器通常足夠聰明,自己就能夠忽略 JavaScript 代碼。
不支持 JavaScript 的瀏覽器另外令人關(guān)注的是如何提供替代的內(nèi)容。隱藏代碼只是解決方法的一部分,開發(fā)者還需要一種方法,聲明在 JavaScript 不能用時(shí)應(yīng)該顯示的內(nèi)容。解決方法是采用 <noscript/> 標(biāo)簽,它可包含任何 HTML 代碼(除 <script/> )。支持或啟用 JavaScript 的瀏覽器會(huì)忽略這些 HTML 代碼,不支持或者禁用 JavaScript 的瀏覽器則顯示 <noscript/> 的內(nèi)容。例如:
在這個(gè)例子中, <noscript/> 標(biāo)簽中有一條消息,告訴用戶瀏覽器不支持 JavaScript 。第 8 章解釋 <noscript/> 的實(shí)際用法。
近來,隨著 XHTML (可擴(kuò)展 HTML )標(biāo)準(zhǔn)的出現(xiàn), <script/> 標(biāo)簽也經(jīng)歷了一些改變。該標(biāo)簽不再用 language 特性,而用 type 特性聲明內(nèi)嵌代碼或要加入的外部文件的 mime 類型, JavaScript 的 mime 類型是 "text/javascript" 。例如:
即使許多瀏覽器不完全支持 XHTML ,但大多數(shù)開發(fā)者現(xiàn)在都用 type 特性,而不用 language 特性,以提供更好的 XHTML 支持。省略 language 特性不會(huì)帶來任何問題,因?yàn)槿缜八觯袨g覽器都默認(rèn) <script/> 的該屬性值為 JavaScript 。
XHTML 的第二個(gè)改變是使用 CDATA 段。 XML 中的 CDATA 段用于聲明不應(yīng)被解析為標(biāo)簽的文本( XHTML 也是如此),這樣就可以使用特殊字符,如小于( < )、大于( > )、和號(hào)( & )和雙引號(hào)( " ),而不必使用它們的字符實(shí)體。考慮下面的代碼:
這個(gè)函數(shù)相當(dāng)簡單,它比較數(shù)字 a 和 b ,然后顯示消息說明它們的關(guān)系。但是,在 XHTML 中,這段代碼是無效的,因?yàn)樗褂昧巳齻€(gè)特殊符號(hào),即小于、大于和雙引號(hào)。要修正這個(gè)問題,必須分別用這三個(gè)字符的 XML 實(shí)體 < 、 > 和 " 替換它們:
這段代碼存在兩個(gè)問題。首先,開發(fā)者不習(xí)慣用 XML 實(shí)體編寫代碼。這使代碼很難讀懂。其次,在 JavaScript 中,這種代碼實(shí)際上將視為有語法錯(cuò),因?yàn)榻忉尦绦虿恢? XML 實(shí)體的意思。用 CDATA 段即可以以常規(guī)形式(即易讀的語法)編寫 JavaScript 代碼。正式加入 CDATA 段的方法如下:
雖然這是正式方式,但還要記住,大多數(shù)瀏覽器都不完全支持 XHTML ,這就帶來主要問題,即這在 JavaScript 中是個(gè)語法錯(cuò)誤,因?yàn)榇蠖鄶?shù)瀏覽器還不認(rèn)識(shí) CDATA 段。
當(dāng)前使用的解決方案模仿了“對(duì)舊瀏覽器隱藏”代碼的方法。使用單行的 JavaScript 注釋,可在不影響代碼語法的情況下嵌入 CDATA 段:
現(xiàn)在,這段代碼在不支持 XHTML 的瀏覽器中也可運(yùn)行。
與 type 特性一樣,隨著開發(fā)者為瀏覽器中的 XHTML 準(zhǔn)備更好的支持, CDATA 的這種用法也越來越流行。但是,為避免 CDATA 的問題,最好還是用外部文件引入 JavaScript 代碼。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
