客戶端JavaScript
web瀏覽器中的JavaScript
一. 客戶端JavaScript
1. document
web 瀏覽器中呈現(xiàn)靜態(tài)信息的頁面叫做文檔(由于加入了JavaScript,靜態(tài)頁面的信息看上去會動來動去,但信息本身是靜態(tài)的)
2. window
Window對象是所有客戶端JavaScript特性和API的主要接入點,是一個全局對象,處于作用域鏈的頂部。引用自身:
windowWindow對象的屬性(全局變量):location屬性(指代Location對象,Location對象指定當(dāng)前顯示在窗口中的URL)、document(引用Document對象,Document對象表示窗口中的文檔)
window.location = "http://www.oreilly.com/";
//設(shè)置location屬性,從而跳轉(zhuǎn)到新的web頁面
-
Window對象的方法(全局函數(shù)):alert(),setTimeout()等
4. 事件處理程序
- 事件處理程序的屬性名是以
on開始的。 - 為事件處理程序綁定一個函數(shù),函數(shù)會在某個事件發(fā)生時以異步的方式調(diào)用。
-
Window對象的onload處理程序是最重要的事件處理程序之一。當(dāng)顯示在窗口中的文檔內(nèi)容穩(wěn)定并可以操作時會觸發(fā)它。
5. JavaScript的角色
- 動態(tài)
HTML或DHTML:JavaScript程序可以通過Document對象和它包含的Element對象遍歷和管理文檔的內(nèi)容。它可以通過操縱CSS樣式和類,修改文檔內(nèi)容的呈現(xiàn)。并且可以通過注冊適當(dāng)?shù)臅r間處理程序來定義文檔元素的行為。內(nèi)容、呈現(xiàn)和行為的組合,叫做動態(tài)HTML或DHTML。 -
Web文檔里的JavaScript:設(shè)計良好的文檔需要在禁用JavaScript后還能工作。JavaScript用于增強用戶的瀏覽體驗,使信息的獲取和傳遞更加容易。如可通過以下方式: - 創(chuàng)建動畫和其他視覺效果,巧妙地引導(dǎo)和幫助用戶進行頁面導(dǎo)航;
- 對表格的列進行分組,讓用戶更容易找到所需要的;
- 隱藏某些內(nèi)容,當(dāng)用戶“深入”到內(nèi)容時,再逐漸展示詳細信息。
-
Web應(yīng)用里的JavaScript:JavaScript訪問瀏覽器提供的高級服務(wù)(比如網(wǎng)絡(luò)、圖像和數(shù)據(jù)存儲),例如常見的XMLHttpRequest對象。
二. 在 HTML 里嵌入 JavaScript
1. 內(nèi)聯(lián),放置在 <script> 和 </script> 之間;
2. 放置在由 <script> 標(biāo)簽的 src 屬性指定的外部文件中;(最好)
- 可以把大塊
JavaScript代碼從HTML文件中刪除,這有助于保持內(nèi)容和行為的分離,從而簡化HTML文件。
- 如果多個
web頁面共用相同的JavaScript代碼,用src屬性可以讓你只管理一份代碼,而不用在代碼改變時編輯每個HTML文件。 - 如果一個
JavaScript代碼文件由多個頁面共享,就只需要下載它一次,通過使用它的第一個頁面,隨后的頁面可以從瀏覽器緩存檢索它。 - 由于
src屬性的值可以是任意的URL,因此來自一個 web 服務(wù)器的JavaScript程序或 web 頁面可以使用由另一個 web 服務(wù)器輸出的代碼。
3. 放置在 HTML 事件處理程序中,該事件處理程序由 onclick 或 onmouseover 這樣的 HTML 屬性值指定。
4. 放置一個 URL 里,這個 URL 使用特殊的 “javascript:” 協(xié)議。
三. JavaScript 程序的執(zhí)行
1. JavaScript 程序執(zhí)行的兩個階段
第一個階段,載入文檔內(nèi)容,并執(zhí)行 <script> 元素里的代碼(包括內(nèi)聯(lián)腳本和外部腳本)。腳本通常會按照它們在文檔里出現(xiàn)的順序執(zhí)行。所有腳本里的 JavaScript 代碼都是從上往下,按照它在條件、循環(huán)以及其他控制語句中的出現(xiàn)順序執(zhí)行的。
文檔載入完成,并且所有腳本執(zhí)行完成后, JavaScript 執(zhí)行進入第二階段。這個階段是異步的,而且是由事件驅(qū)動的。在事件驅(qū)動階段, web 瀏覽器調(diào)用事件處理程序函數(shù)來響應(yīng)異步發(fā)生的事件,調(diào)用事件處理程序通常是響應(yīng)用戶輸入,還可以由網(wǎng)絡(luò)活動、運行時間或者 JavaScript 代碼中的錯誤來觸發(fā)。
JavaScript 是單線程執(zhí)行的,腳本和事件處理程序在同一個時間只能執(zhí)行一個,沒有并發(fā)性,這保持了 JavaScript 編程的簡單性。單線程執(zhí)行時為了讓編程更加簡單,編寫代碼時可以確保兩個事件處理程序不會同一時刻運行,操作文檔內(nèi)容時也不必擔(dān)心會有其他線程試圖同時修改文檔。
單線程執(zhí)行意味著瀏覽器必須在腳本和事件句處理程序執(zhí)行的時候停止響應(yīng)用戶輸入。
2. 同步、異步和延遲的腳本
當(dāng)HTML解析器遇到 <script> 元素時,它默認必須先執(zhí)行腳本,然后再恢復(fù)文檔的解析和渲染。這對于內(nèi)聯(lián)腳本沒什么問題,但是如果腳本源代碼時一個由 src 屬性指定的外部文件,這意味著腳本后面的文檔部分在下載和執(zhí)行腳本之前,都不會出現(xiàn)在瀏覽器中。
腳本的執(zhí)行只是在默認的情況下是同步和阻塞的。
<script> 標(biāo)簽可以有 defer 和 async 屬性,這可以改變腳本的執(zhí)行方式。瀏覽器可以在加載腳本時繼續(xù)解析和渲染文檔。
defer 屬性使得瀏覽器延遲腳本的執(zhí)行,直到文檔的載入和解析完成,并可以操作。(先載入文檔,再執(zhí)行腳本)
aync 屬性使得瀏覽器可以盡快地執(zhí)行腳本,而不用在下載腳本時阻塞文檔解析。(同時執(zhí)行腳本和解析文檔)
如果 <script> 標(biāo)簽同時有兩個屬性,同時支持兩者的瀏覽器會遵從 async 屬性并忽略 defer 屬性。
延遲的腳本會按它們在文檔里的出現(xiàn)順序執(zhí)行,而異步腳本在它們載入后執(zhí)行,這意味著它們可能會無序執(zhí)行。
3. 事件驅(qū)動的 JavaScript
- 事件的名字:
click,change等指示發(fā)生的事件的通用類型。 - 事件的目標(biāo):是一個對象,并且事件就是在它上面發(fā)生的。
- 如果想要程序響應(yīng)一個事件,寫一個函數(shù),叫做“事件處理程序”“事件監(jiān)聽器”或“回調(diào)”。然后注冊這個函數(shù),這樣他就會在事件發(fā)生時調(diào)用它。
- 注冊事件處理程序最簡單的方法是把
JavaScript函數(shù)賦值給目標(biāo)對象的屬性。
function handleResponse() {...}
request.onreadystatechange = handleResponse;
- 事件處理程序的屬性的名字是以
on開始,后面跟著事件的名字。還要注意在上面的任何代碼里<strong>沒有函數(shù)調(diào)用</strong>:只是把函數(shù)本身賦值給這些屬性。瀏覽器會在事件發(fā)生時執(zhí)行調(diào)用。 - 為一個事件注冊多個事件處理程序函數(shù),大部分可以用
addEventListener()方法,允許注冊多個監(jiān)聽器。
ie9之前用attachEvent()方法 - 傳遞給
setTimeout()的函數(shù)和真實事件處理程序的注冊不同,他們通常叫做“回調(diào)邏輯”而不是“處理程序”,但他們也是異步的。
4. 客戶端 JavaScript 時間線
web 瀏覽器創(chuàng)建
Document對象,并且開始解析web頁面,解析HTML元素和它們的文本內(nèi)容后添加Element對象和Text節(jié)點到文檔中。在這個階段document.readyState屬性的值是loading當(dāng)
HTML解析器遇到?jīng)]有async和defer屬性的<script>元素時,它把這些元素添加到文檔中,然后執(zhí)行行內(nèi)或外部腳本。這些腳本會同步執(zhí)行,并且在腳本下載和執(zhí)行時解析器會暫停。這樣腳本就可以用document.write()來把文本插入到輸入流中。解析器恢復(fù)時這些文本會成為文檔的一部分。同步腳本經(jīng)常簡單定義函數(shù)和注冊后面使用的注冊事件處理程序,但它們可以遍歷和操作文檔樹,因為在它們執(zhí)行時已經(jīng)存在了。這樣,同步腳本可以看到它自己的<script>元素和它們之前的文檔內(nèi)容。當(dāng)解析器遇到設(shè)置了
async屬性的<script>元素時,它開始下載腳本文本,并繼續(xù)解析文檔。腳本會在它載入完成后盡快執(zhí)行,但是解析器沒有停下來等它下載。異步腳本禁止使用document.write()方法。它們可以看到自己的<script>元素和它之前的所有文檔元素,并且可能或者干脆不可能訪問其他的文檔內(nèi)容。當(dāng)文檔完成解析,
document.readystate屬性變成interactive。所有有
defer屬性的腳本,會按它們在文檔里的出現(xiàn)順序執(zhí)行。異步腳本可能也會在在這個時間執(zhí)行。延遲腳本能訪問完整的文檔樹,禁止使用document.write()方法。瀏覽器在
Document對象上觸發(fā)DOMContentLoaded事件。這標(biāo)志著程序執(zhí)行從同步腳本執(zhí)行階段轉(zhuǎn)換到了異步事件驅(qū)動階段。但要注意,這時可能還有異步腳本沒有執(zhí)行完成。這時,文檔已經(jīng)完全解析完成,但是瀏覽器可能還在等待其他內(nèi)容載入,如圖片。當(dāng)所有這些內(nèi)容完成載入時,并且所有異步腳本完成載入和執(zhí)行,
document.readyState屬性改變?yōu)?complete,web 瀏覽器觸發(fā)Window對象上的load事件。從此刻起,會調(diào)用異步事件,以異步響應(yīng)用戶輸入事件、網(wǎng)絡(luò)事件、計時器過期等。
四. 兼容性和互用性
- 客戶端
JavaScript兼容性和交互性的問題可以歸納為: - 演化:不同的瀏覽器、新特性
- 未實現(xiàn):有些現(xiàn)代瀏覽器實現(xiàn)的功能在老舊瀏覽器中沒實現(xiàn)。
同樣實現(xiàn)一個功能在不同瀏覽器中有很大差別。 - bug:每個瀏覽器都有
bug,并且沒有按照規(guī)范準(zhǔn)確地實現(xiàn)所有客戶端的JavaScript API。 - 處理不兼容問題其中一種最簡單的方法是使用類庫。
- 功能測試:
if (element.addEventListener) {
element.addEventListener("keydown",handler,false);
element.addEventListener("keypress",handler,false);
}
else if (element.attachEvent) {
element.attachEvent("onkeydown",handler);
element.attachEvent("onkeypress",handler);
}
else {
element.onkeydown = element.onkeypress = handler;
}
- 瀏覽器測試:確定當(dāng)前瀏覽器的廠商和版本的代碼通常叫做瀏覽器嗅探器或者客戶端嗅探器。
- IE里的條件注釋
- html里的條件注釋
<!--[if IE6]>
this content is actually inside an html comment.
it will only be displayed in IE6
<![endif]-->
<!--[if lte IE7]>
displayed by IE5,6 and 7 and earlier
<![endif]-->
<!--[if !IE]><-->
IE will not display id
<!--><![endif]-->
- javascript 里的條件注釋:
/*@cc_on
@if (@_jscript)
alert("In IE");
@end
@*/
五. 可訪問性
- 如果你設(shè)計的站點過于依賴
JavaScript來呈現(xiàn)數(shù)據(jù)的話,可能會把讀屏軟件的用戶拒之門外,因為一些讀屏軟件只能在禁用JavaScript時才會工作得更好。 -
JavaScript的角色應(yīng)該是增加信息的表現(xiàn)力,而不是負責(zé)信息的呈現(xiàn)。 -
JavaScript可訪問性的一條重要原則是,設(shè)計的代碼即使在禁用JavaScript解釋器的瀏覽器中也能正常使用。
六. 安全性
瀏覽器針對惡意代碼的第一條防線就是它們不支持某些功能:
客戶端
JavaScript沒有權(quán)限來寫入或刪除客戶計算機上的任意文件或列出任意目錄。客戶端
JavaScript沒有任何通用的網(wǎng)絡(luò)能力。瀏覽器針對而已代碼的第二條防線是在自己支持的某些功能上施加限制,如:
限制打開新窗口的功能。
不允許未經(jīng)用戶允許關(guān)閉用戶打開的窗口。
HTML FileUpload的value屬性是只讀的。腳本不能讀取從不同服務(wù)器載入的文檔的內(nèi)容,除非這個就是包含該腳本的文檔。一個腳本不能再來自不同服務(wù)器的文檔上注冊事件監(jiān)聽器。
同源策略:是對
JavaScript代碼能夠操作哪些web內(nèi)容的一條完整的安全限制。跨站腳本(XSS),用來表示一類安全問題,也就是攻擊者向目標(biāo)
web站點注入html標(biāo)簽或者腳本。
防止XSS攻擊的方式是,在使用任何不可信的數(shù)據(jù)來動態(tài)的創(chuàng)建文檔內(nèi)容之前,從中移除html標(biāo)簽。拒絕服務(wù)攻擊:如果訪問了啟用
JavaScript功能的一個惡意web站點,這個站點可以使用一個alert()對話框的無限循環(huán)占用瀏覽器,或者用一個無限循環(huán)或沒有意義的計算來占用CPU。
————————————————分割線—————————————————
END:Answer
Window對象是全局對象,它有屬性和方法,alert()方法是它的一個方法,是一個全局函數(shù),可以直接使用。
DOM: document object model 文檔對象模型
BOM: browser object model 瀏覽器對象模型
BOM的最根本對象是window,是對瀏覽器窗口的操作。
DOM的最根本對象是document,是對頁面文檔的操作。
BOM包含DOM。
DOM常用來獲取文檔的節(jié)點、元素,操作他們的樣式呈現(xiàn)和行為。
JavaScript的DOM常用來增強用戶體驗。
一個瀏覽器進程中一般有四個線程:javascript引擎線程、渲染引擎線程、瀏覽器事件線程、http請求線程。同步:等前一個任務(wù)完成之后再執(zhí)行下一個任務(wù),是順序的。如果前一個任務(wù)耗時很長,后一個任務(wù)將總是等不到執(zhí)行。
異步:后一個任務(wù)是通過前一個任務(wù)執(zhí)行回調(diào)執(zhí)行的。<script>標(biāo)簽可以是內(nèi)聯(lián)的,放在html文檔中,當(dāng)解析的時候遇到內(nèi)聯(lián)的<script>標(biāo)簽的時候就會停止文檔的解析,執(zhí)行腳本代碼。直到腳本執(zhí)行完后繼續(xù)解析文檔。
<script>標(biāo)簽放在<head>標(biāo)簽中,文檔的解析要等到腳本全部加載完后才解析。
<script>標(biāo)簽放在</body>前,先解析文檔,再執(zhí)行腳本代碼。事件驅(qū)動三要素:事件、事件的目標(biāo)、事件回調(diào)函數(shù)。
事件處理機制:事件冒泡、事件傳播、事件捕獲、事件委托。JavaScript 是單線程的,默認是同步的,阻塞的;可以通過 defer 和 async 屬性改變腳本的執(zhí)行方式。