客戶端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/";
//設(shè)置location屬性,從而跳轉(zhuǎn)到新的web頁面
-
Window
對象的方法(全局函數(shù)):alert(),setTimeout()
等
4. 事件處理程序
- 事件處理程序的屬性名是以
on
開始的层玲。 - 為事件處理程序綁定一個函數(shù)辛块,函數(shù)會在某個事件發(fā)生時以異步的方式調(diào)用铅碍。
-
Window
對象的onload
處理程序是最重要的事件處理程序之一。當顯示在窗口中的文檔內(nèi)容穩(wěn)定并可以操作時會觸發(fā)它。
5. JavaScript的角色
- 動態(tài)
HTML
或DHTML
:JavaScript
程序可以通過Document
對象和它包含的Element
對象遍歷和管理文檔的內(nèi)容士嚎。它可以通過操縱CSS
樣式和類,修改文檔內(nèi)容的呈現(xiàn)爵嗅。并且可以通過注冊適當?shù)臅r間處理程序來定義文檔元素的行為笨蚁。內(nèi)容、呈現(xiàn)和行為的組合伪很,叫做動態(tài)HTML
或DHTML
奋单。 -
Web
文檔里的JavaScript
:設(shè)計良好的文檔需要在禁用JavaScript
后還能工作览濒。JavaScript
用于增強用戶的瀏覽體驗拖云,使信息的獲取和傳遞更加容易宙项。如可通過以下方式: - 創(chuàng)建動畫和其他視覺效果株扛,巧妙地引導(dǎo)和幫助用戶進行頁面導(dǎo)航;
- 對表格的列進行分組叔磷,讓用戶更容易找到所需要的奖磁;
- 隱藏某些內(nèi)容,當用戶“深入”到內(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> 標簽的 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)容時也不必擔心會有其他線程試圖同時修改文檔篓吁。
單線程執(zhí)行意味著瀏覽器必須在腳本和事件句處理程序執(zhí)行的時候停止響應(yīng)用戶輸入蚪拦。
2. 同步冻押、異步和延遲的腳本
當HTML解析器遇到 <script>
元素時洛巢,它默認必須先執(zhí)行腳本狼渊,然后再恢復(fù)文檔的解析和渲染类垦。這對于內(nèi)聯(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. 事件驅(qū)動的 JavaScript
- 事件的名字:
click
傲须,change
等指示發(fā)生的事件的通用類型。 - 事件的目標:是一個對象例衍,并且事件就是在它上面發(fā)生的已卸。
- 如果想要程序響應(yīng)一個事件累澡,寫一個函數(shù),叫做“事件處理程序”“事件監(jiān)聽器”或“回調(diào)”永乌。然后注冊這個函數(shù)翅雏,這樣他就會在事件發(fā)生時調(diào)用它。
- 注冊事件處理程序最簡單的方法是把
JavaScript
函數(shù)賦值給目標對象的屬性绩脆。
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
當
HTML
解析器遇到?jīng)]有async
和defer
屬性的<script>
元素時帚呼,它把這些元素添加到文檔中皱蹦,然后執(zhí)行行內(nèi)或外部腳本。這些腳本會同步執(zhí)行沈自,并且在腳本下載和執(zhí)行時解析器會暫停枯途。這樣腳本就可以用document.write()
來把文本插入到輸入流中籍滴。解析器恢復(fù)時這些文本會成為文檔的一部分孽惰。同步腳本經(jīng)常簡單定義函數(shù)和注冊后面使用的注冊事件處理程序,但它們可以遍歷和操作文檔樹坦报,因為在它們執(zhí)行時已經(jīng)存在了。這樣燎竖,同步腳本可以看到它自己的<script>
元素和它們之前的文檔內(nèi)容构回。當解析器遇到設(shè)置了
async
屬性的<script>
元素時纤掸,它開始下載腳本文本,并繼續(xù)解析文檔借跪。腳本會在它載入完成后盡快執(zhí)行酌壕,但是解析器沒有停下來等它下載。異步腳本禁止使用document.write()
方法果港。它們可以看到自己的<script>
元素和它之前的所有文檔元素辛掠,并且可能或者干脆不可能訪問其他的文檔內(nèi)容释牺。當文檔完成解析没咙,
document.readystate
屬性變成interactive
。所有有
defer
屬性的腳本预柒,會按它們在文檔里的出現(xiàn)順序執(zhí)行袁梗。異步腳本可能也會在在這個時間執(zhí)行宜鸯。延遲腳本能訪問完整的文檔樹,禁止使用document.write()
方法遮怜。瀏覽器在
Document
對象上觸發(fā)DOMContentLoaded
事件淋袖。這標志著程序執(zhí)行從同步腳本執(zhí)行階段轉(zhuǎn)換到了異步事件驅(qū)動階段。但要注意锯梁,這時可能還有異步腳本沒有執(zhí)行完成即碗。這時焰情,文檔已經(jīng)完全解析完成内舟,但是瀏覽器可能還在等待其他內(nèi)容載入验游,如圖片保檐。當所有這些內(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ī)范準確地實現(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
@*/
五. 可訪問性
- 如果你設(shè)計的站點過于依賴
JavaScript
來呈現(xiàn)數(shù)據(jù)的話票腰,可能會把讀屏軟件的用戶拒之門外杏慰,因為一些讀屏軟件只能在禁用JavaScript
時才會工作得更好缘滥。 -
JavaScript
的角色應(yīng)該是增加信息的表現(xiàn)力朝扼,而不是負責信息的呈現(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)片排,用來表示一類安全問題率寡,也就是攻擊者向目標
web
站點注入html
標簽或者腳本冶共。
防止XSS攻擊的方式是捅僵,在使用任何不可信的數(shù)據(jù)來動態(tài)的創(chuàng)建文檔內(nèi)容之前庙楚,從中移除html
標簽馒闷。拒絕服務(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>標簽可以是內(nèi)聯(lián)的冲秽,放在html文檔中锉桑,當解析的時候遇到內(nèi)聯(lián)的<script>標簽的時候就會停止文檔的解析民轴,執(zhí)行腳本代碼后裸。直到腳本執(zhí)行完后繼續(xù)解析文檔微驶。
<script>標簽放在<head>標簽中祈搜,文檔的解析要等到腳本全部加載完后才解析。
<script>標簽放在</body>前婚度,先解析文檔蝗茁,再執(zhí)行腳本代碼哮翘。事件驅(qū)動三要素:事件阻课、事件的目標限煞、事件回調(diào)函數(shù)署驻。
事件處理機制:事件冒泡旺上、事件傳播抚官、事件捕獲凌节、事件委托。JavaScript 是單線程的卒煞,默認是同步的畔裕,阻塞的扮饶;可以通過 defer 和 async 屬性改變腳本的執(zhí)行方式甜无。