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