本書前面討論過,HTML5規(guī)范定義了很多新HTML標記。為了配合這些標記的變化,HTML5規(guī)范也用顯著篇幅定義了很多JavaScript API。定義這些API的用意就是簡化此前實現(xiàn)起來困難重重的任務,最終簡化創(chuàng)建動態(tài)Web界面的工作。
跨文檔消息傳送(cross-document messaging),有時候簡稱為XDM,指的是在來自不同域的頁面間傳遞消息。例如,www.wrox.com域中的頁面與位于一個內嵌框架中的p2p.wrox.com域中的頁面通信。在XDM機制出現(xiàn)之前,要穩(wěn)妥地實現(xiàn)這種通信需要花很多工夫。XDM把這種機制規(guī)范化,讓我們能既穩(wěn)妥又簡單地實現(xiàn)跨文檔通信。
XDM的核心是postMessage()方法。在HTML5規(guī)范中,除了XDM部分之外的其他部分也會提到這個方法名,但都是為了同一個目的:向另一個地方傳遞數(shù)據(jù)。對于XDM而言,“另一個地方”指的是包含在當前頁面中的元素,或者由當前頁面彈出的窗口。
postMessage()方法接收兩個參數(shù):一條消息和一個表示消息接收方來自哪個域的字符串。第二個參數(shù)對保障安全通信非常重要,可以防止瀏覽器把消息發(fā)送到不安全的地方。來看下面的例子。
//注意:所有支持XDM的瀏覽器也支持iframe的contentWindow屬性
var iframeWindow = document.getElementById("myframe").contentWindow;iframeWindow.postMessage("A secret", "http://www.wrox.com");
最后一行代碼嘗試向內嵌框架中發(fā)送一條消息,并指定框架中的文檔必須來源于"http:// www.wrox.com"域。如果來源匹配,消息會傳遞到內嵌框架中;否則,postMessage()什么也不做。這一限制可以避免窗口中的位置在你不知情的情況下發(fā)生改變。如果傳給postMessage()的第二個參數(shù)是"*",則表示可以把消息發(fā)送給來自任何域的文檔,但我們不推薦這樣做。
接收到XDM消息時,會觸發(fā)window對象的message事件。這個事件是以異步形式觸發(fā)的,因此從發(fā)送消息到接收消息(觸發(fā)接收窗口的message事件)可能要經(jīng)過一段時間的延遲。觸發(fā)message事件后,傳遞給onmessage處理程序的事件對象包含以下三方面的重要信息。
接收到消息后驗證發(fā)送窗口的來源是至關重要的。就像給postMessage()方法指定第二個參數(shù),以確保瀏覽器不會把消息發(fā)送給未知頁面一樣,在onmessage處理程序中檢測消息來源可以確保傳入的消息來自已知的頁面。基本的檢測模式如下。
EventUtil.addHandler(window, "message", function(event){
//確保發(fā)送消息的域是已知的域if (event.origin == "http://www.wrox.com"){ //處理接收到的數(shù)據(jù) processMessage(event.data); //可選:向來源窗口發(fā)送回執(zhí) event.source.postMessage("Received!", "http://p2p.wrox.com");}
});
還是要提醒大家,event.source大多數(shù)情況下只是window對象的代理,并非實際的window對象。換句話說,不能通過這個代理對象訪問window對象的其他任何信息。記住,只通過這個代理調用postMessage()就好,這個方法永遠存在,永遠可以調用。
XDM還有一些怪異之處。首先,postMessage()的第一個參數(shù)最早是作為“永遠都是字符串”來實現(xiàn)的。但后來這個參數(shù)的定義改了,改成允許傳入任何數(shù)據(jù)結構??墒?,并非所有瀏覽器都實現(xiàn)了這一變化。為保險起見,使用postMessage()時,最好還是只傳字符串。如果你想傳入結構化的數(shù)據(jù),最佳選擇是先在要傳入的數(shù)據(jù)上調用JSON.stringify(),通過postMessage()傳入得到的字符串,然后再在onmessage事件處理程序中調用JSON.parse()。
在通過內嵌框架加載其他域的內容時,使用XDM是非常方便的。因此,在混搭(mashup)和社交網(wǎng)絡應用中,這種傳遞消息的方法極為常用。有了XDM,包含的頁面可以確保自身不受惡意內容的侵擾,因為它只通過XDM與嵌入的框架通信。而XDM也可以在來自相同域的頁面間使用。
支持XDM的瀏覽器有IE8+、Firefox 3.5+、Safari 4+、Opera、Chrome、iOS版Safari及Android版WebKit。XDM已經(jīng)作為一個規(guī)范獨立出來,現(xiàn)在它的名字叫Web Messaging,官方頁面是http://dev.w3.org/html5/postmsg/。
最早在網(wǎng)頁中引入JavaScript拖放功能的是IE4。當時,網(wǎng)頁中只有兩種對象可以拖放:圖像和某些文本。拖動圖像時,把鼠標放在圖像上,按住鼠標不放就可以拖動它。拖動文本時,要先選中文本,然后可以像拖動圖像一樣拖動被選中的文本。在IE 4中,唯一有效的放置目標是文本框。到了IE5,拖放功能得到擴展,添加了新的事件,而且?guī)缀蹙W(wǎng)頁中的任何元素都可以作為放置目標。IE5.5更進一步,讓網(wǎng)頁中的任何元素都可以拖放。(IE6同樣也支持這些功能。)HTML5以IE的實例為基礎制定了拖放規(guī)范。Firefox 3.5、Safari 3+和Chrome也根據(jù)HTML5規(guī)范實現(xiàn)了原生拖放功能。
說到拖放,最有意思的恐怕就是能夠在框架間、窗口間,甚至在應用間拖放網(wǎng)頁元素了。瀏覽器對拖放的支持為實現(xiàn)這些功能提供了便利。
通過拖放事件,可以控制拖放相關的各個方面。其中最關鍵的地方在于確定哪里發(fā)生了拖放事件,有些事件是在被拖動的元素上觸發(fā)的,而有些事件是在放置目標上觸發(fā)的。拖動某元素時,將依次觸發(fā)下列事件:
(1) dragstart
(2) drag
(3) dragend
按下鼠標鍵并開始移動鼠標時,會在被拖放的元素上觸發(fā)dragstart事件。此時光標變成“不能放”符號(圓環(huán)中有一條反斜線),表示不能把元素放到自己上面。拖動開始時,可以通過ondragstart事件處理程序來運行JavaScript代碼。
觸發(fā)dragstart事件后,隨即會觸發(fā)drag事件,而且在元素被拖動期間會持續(xù)觸發(fā)該事件。這個事件與mousemove事件相似,在鼠標移動過程中,mousemove事件也會持續(xù)發(fā)生。當拖動停止時(無論是把元素放到了有效的放置目標,還是放到了無效的放置目標上),會觸發(fā)dragend事件。
上述三個事件的目標都是被拖動的元素。默認情況下,瀏覽器不會在拖動期間改變被拖動元素的外觀,但你可以自己修改。不過,大多數(shù)瀏覽器會為正被拖動的元素創(chuàng)建一個半透明的副本,這個副本始終跟隨著光標移動。
當某個元素被拖動到一個有效的放置目標上時,下列事件會依次發(fā)生: (1) dragenter (2) dragover (3)
dragleave或drop
只要有元素被拖動到放置目標上,就會觸發(fā)dragenter事件(類似于mouseover事件)。緊隨其后的是dragover事件,而且在被拖動的元素還在放置目標的范圍內移動時,就會持續(xù)觸發(fā)該事件。如果元素被拖出了放置目標,dragover事件不再發(fā)生,但會觸發(fā)dragleave事件(類似于mouseout事件)。如果元素被放到了放置目標中,則會觸發(fā)drop事件而不是dragleave事件。上述三個事件的目標都是作為放置目標的元素。
在拖動元素經(jīng)過某些無效放置目標時,可以看到一種特殊的光標(圓環(huán)中有一條反斜線),表示不能放置。雖然所有元素都支持放置目標事件,但這些元素默認是不允許放置的。如果拖動元素經(jīng)過不允許放置的元素,無論用戶如何操作,都不會發(fā)生drop事件。不過,你可以把任何元素變成有效的放置目標,方法是重寫dragenter和dragover事件的默認行為。例如,假設有一個ID為"droptarget"的
var droptarget = document.getElementById("droptarget");EventUtil.addHandler(droptarget, "dragover", function(event){ EventUtil.preventDefault(event);});EventUtil.addHandler(droptarget, "dragenter", function(event){ EventUtil.preventDefault(event);});
以上代碼執(zhí)行后,你就會發(fā)現(xiàn)當拖動著元素移動到放置目標上時,光標變成了允許放置的符號。當然,釋放鼠標也會觸發(fā)drop事件。
在Firefox 3.5+中,放置事件的默認行為是打開被放到放置目標上的URL。換句話說,如果是把圖像拖放到放置目標上,頁面就會轉向圖像文件;而如果是把文本拖放到放置目標上,則會導致無效URL錯誤。因此,為了讓Firefox支持正常的拖放,還要取消drop事件的默認行為,阻止它打開URL:
EventUtil.addHandler(droptarget, "drop", function(event){ EventUtil.preventDefault(event); });
只有簡單的拖放而沒有數(shù)據(jù)變化是沒有什么用的。為了在拖放操作時實現(xiàn)數(shù)據(jù)交換,IE 5引入了dataTransfer對象,它是事件對象的一個屬性,用于從被拖動元素向放置目標傳遞字符串格式的數(shù)據(jù)。因為它是事件對象的屬性,所以只能在拖放事件的事件處理程序中訪問dataTransfer對象。在事件處理程序中,可以使用這個對象的屬性和方法來完善拖放功能。目前,HTML5規(guī)范草案也收入了dataTransfer對象。
dataTransfer對象有兩個主要方法:getData()和setData()。不難想象,getData()可以取得由setData()保存的值。setData()方法的第一個參數(shù),也是getData()方法唯一的一個參數(shù),是一個字符串,表示保存的數(shù)據(jù)類型,取值為"text"或"URL",如下所示:
//設置和接收文本數(shù)據(jù)event.dataTransfer.setData("text", "some text");var text = event.dataTransfer.getData("text");//設置和接收URLevent.dataTransfer.setData("URL", "http://www.wrox.com/");var url = event.dataTransfer.getData("URL");
IE只定義了"text"和"URL"兩種有效的數(shù)據(jù)類型,而HTML5則對此加以擴展,允許指定各種MIME類型??紤]到向后兼容,HTML5也支持"text"和"URL",但這兩種類型會被映射為"text/plain"和"text/uri-list"。
實際上,dataTransfer對象可以為每種MIME類型都保存一個值。換句話說,同時在這個對象中保存一段文本和一個URL不會有任何問題。不過,保存在dataTransfer對象中的數(shù)據(jù)只能在drop事件處理程序中讀取。如果在ondrop處理程序中沒有讀到數(shù)據(jù),那就是dataTransfer對象已經(jīng)被銷毀,數(shù)據(jù)也丟失了。
在拖動文本框中的文本時,瀏覽器會調用setData()方法,將拖動的文本以"text"格式保存在dataTransfer對象中。類似地,在拖放鏈接或圖像時,會調用setData()方法并保存URL。然后,在這些元素被拖放到放置目標時,就可以通過getData()讀到這些數(shù)據(jù)。當然,作為開發(fā)人員,你也可以在dragstart事件處理程序中調用setData(),手工保存自己要傳輸?shù)臄?shù)據(jù),以便將來使用。
將數(shù)據(jù)保存為文本和保存為URL是有區(qū)別的。如果將數(shù)據(jù)保存為文本格式,那么數(shù)據(jù)不會得到任何特殊處理。而如果將數(shù)據(jù)保存為URL,瀏覽器會將其當成網(wǎng)頁中的鏈接。換句話說,如果你把它放置到另一個瀏覽器窗口中,瀏覽器就會打開該URL。
Firefox在其第5個版本之前不能正確地將"url"和"text"映射為"text/uri-list"和"text/plain"。但是卻能把"Text"(T大寫)映射為"text/plain"。為了更好地在跨瀏覽器的情況下從dataTransfer對象取得數(shù)據(jù),最好在取得URL數(shù)據(jù)時檢測兩個值,而在取得文本數(shù)據(jù)時使用"Text"。
var dataTransfer = event.dataTransfer;//讀取URLvar url = dataTransfer.getData("url") ||dataTransfer.getData("text/uri-list");//讀取文本var text = dataTransfer.getData("Text");
DataTransferExample01.htm
注意,一定要把短數(shù)據(jù)類型放在前面,因為IE 10及之前的版本仍然不支持擴展的MIME類型名,而它們在遇到無法識別的數(shù)據(jù)類型時,會拋出錯誤。
利用dataTransfer對象,可不光是能夠傳輸數(shù)據(jù),還能通過它來確定被拖動的元素以及作為放置目標的元素能夠接收什么操作。為此,需要訪問dataTransfer對象的兩個屬性:dropEffect和effectAllowed。
其中,通過dropEffect屬性可以知道被拖動的元素能夠執(zhí)行哪種放置行為。這個屬性有下列4個可能的值。
在把元素拖動到放置目標上時,以上每一個值都會導致光標顯示為不同的符號。然而,要怎樣實現(xiàn)光標所指示的動作完全取決于你。換句話說,如果你不介入,沒有什么會自動地移動、復制,也不會打開鏈接??傊?,瀏覽器只能幫你改變光標的樣式,而其他的都要靠你自己來實現(xiàn)。要使用dropEffect屬性,必須在ondragenter事件處理程序中針對放置目標來設置它。
dropEffect屬性只有搭配effectAllowed屬性才有用。effectAllowed屬性表示允許拖動元素的哪種dropEffect,effectAllowed屬性可能的值如下。
必須在ondragstart事件處理程序中設置effectAllowed屬性。
假設你想允許用戶把文本框中的文本拖放到一個
Firefox 5及之前的版本在處理effectAllowed屬性時有一個問題,即如果你在代碼中設置了這個屬性的值,那不一定會觸發(fā)drop事件
。
默認情況下,圖像、鏈接和文本是可以拖動的,也就是說,不用額外編寫代碼,用戶就可以拖動它們。文本只有在被選中的情況下才能拖動,而圖像和鏈接在任何時候都可以拖動。
讓其他元素可以拖動也是可能的。HTML5為所有HTML元素規(guī)定了一個draggable屬性,表示元素是否可以拖動。圖像和鏈接的draggable屬性自動被設置成了true,而其他元素這個屬性的默認值都是false。要想讓其他元素可拖動,或者讓圖像或鏈接不能拖動,都可以設置這個屬性。例如:
<!-- 讓這個圖像不可以拖動 --><img src="smile.gif" draggable="false" alt="Smiley face"><!-- 讓這個元素可以拖動 --><div draggable="true">...</div>
支持draggable屬性的瀏覽器有IE 10+、Firefox 4+、Safari 5+和Chrome。Opera 11.5及之前的版本都不支持HTML5的拖放功能。另外,為了讓Firefox支持可拖動屬性,還必須添加一個ondragstart事件處理程序,并在dataTransfer對象中保存一些信息。
在IE9及更早版本中,通過mousedown事件處理程序調用dragDrop()能夠讓任何元素可拖動。而在Safari 4及之前版本中,必須額外給相應元素設置CSS樣式–khtml-user-drag: element。
HTML5規(guī)范規(guī)定dataTransfer對象還應該包含下列方法和屬性。
隨著音頻和視頻在Web上的迅速流行,大多數(shù)提供富媒體內容的站點為了保證跨瀏覽器兼容性,不得不選擇使用Flash。HTML5新增了兩個與媒體相關的標簽,讓開發(fā)人員不必依賴任何插件就能在網(wǎng)頁中嵌入跨瀏覽器的音頻和視頻內容。這兩個標簽就是和。
這兩個標簽除了能讓開發(fā)人員方便地嵌入媒體文件之外,都提供了用于實現(xiàn)常用功能的JavaScript API,允許為媒體創(chuàng)建自定義的控件。這兩個元素的用法如下。
<!-- 嵌入視頻 --><video src="conference.mpg" id="myVideo">Video player not available.</video><!-- 嵌入音頻 --><audio src="song.mp3" id="myAudio">Audio player not available.</audio>
使用這兩個元素時,至少要在標簽中包含src屬性,指向要加載的媒體文件。還可以設置width和height屬性以指定視頻播放器的大小,而為poster屬性指定圖像的URI可以在加載視頻內容期間顯示一幅圖像。另外,如果標簽中有controls屬性,則意味著瀏覽器應該顯示UI控件,以便用戶直接操作媒體。位于開始和結束標簽之間的任何內容都將作為后備內容,在瀏覽器不支持這兩個媒體元素的情況下顯示。
因為并非所有瀏覽器都支持所有媒體格式,所以可以指定多個不同的媒體來源。為此,不用在標簽中指定src屬性,而是要像下面這樣使用一或多個元素。
<!-- 嵌入視頻 --><video id="myVideo"> <source src="conference.webm" type="video/webm; codecs='vp8, vorbis'"> <source src="conference.ogv" type="video/ogg; codecs='theora, vorbis'"> <source src="conference.mpg"> Video player not available.</video><!-- 嵌入音頻 --><audio id="myAudio"> <source src="song.ogg" type="audio/ogg"> <source src="song.mp3" type="audio/mpeg"> Audio player not available.</audio>
關于視頻和音頻編解碼器的內容超出了本書討論的范圍。作者在此只想告訴大家,不同的瀏覽器支持不同的編解碼器,因此一般來說指定多種格式的媒體來源是必需的。支持這兩個媒體元素的瀏覽器有IE9+、Firefox 3.5+、Safari 4+、Opera 10.5+、Chrome、iOS版Safari和Android版WebKit。
和元素都提供了完善的JavaScript接口。下表列出了這兩個元素共有的屬性,通過這些屬性可以知道媒體的當前狀態(tài)。
除了大量屬性之外,這兩個媒體元素還可以觸發(fā)很多事件。這些事件監(jiān)控著不同的屬性的變化,這些變化可能是媒體播放的結果,也可能是用戶操作播放器的結果。下表列出了媒體元素相關的事件。
這些事件之所以如此具體,就是為了讓開發(fā)人員只使用少量HTML和JavaScript(與創(chuàng)建Flash影片相比)即可編寫出自定義的音頻/視頻播放器。
使用和元素的play()和pause()方法,可以手工控制媒體文件的播放。組合使用屬性、事件和這兩個方法,很容易創(chuàng)建一個自定義的媒體播放器,如下面的例子所示。
<div class="mediaplayer"> <div class="video"> <video id="player" src="movie.mov" poster="mymovie.jpg" width="300" height="200"> Video player not available. </video> </div> <div class="controls"> <input type="button" value="Play" id="video-btn"> <span id="curtime">0</span>/<span id="duration">0</span> </div></div>
VideoPlayerExample01.htm
以上基本的HTML再加上一些JavaScript就可以變成一個簡單的視頻播放器。以下就是JavaScript代碼。
//取得元素的引用var player = document.getElementById("player"), btn = document.getElementById("video-btn"), curtime = document.getElementById("curtime"), duration = document.getElementById("duration");//更新播放時間duration.innerHTML = player.duration;//為按鈕添加事件處理程序EventUtil.addHandler(btn, "click", function(event){ if (player.paused){ player.play(); btn.value = "Pause"; } else { player.pause(); btn.value = "Play"; }});//定時更新當前時間setInterval(function(){ curtime.innerHTML = player.currentTime;}, 250);
VideoPlayerExample01.htm
以上JavaScript代碼給按鈕添加了一個事件處理程序,單擊它能讓視頻在暫停時播放,在播放時暫停。通過元素的load事件處理程序,設置了加載完視頻后顯示播放時間。最后,設置了一個計時器,以更新當前顯示的時間。你可以進一步擴展這個視頻播放器,監(jiān)聽更多事件,利用更多屬性。而同樣的代碼也可以用于元素,以創(chuàng)建自定義的音頻播放器。
如前所述,并非所有瀏覽器都支持和的所有編解碼器,而這基本上就意味著你必須提供多個媒體來源。不過,也有一個JavaScript API能夠檢測瀏覽器是否支持某種格式和編解碼器。這兩個媒體元素都有一個canPlayType()方法,該方法接收一種格式/編解碼器字符串,返回"probably"、"maybe"或""( 空字符串)??兆址羌僦?,因此可以像下面這樣在if語句中使用canPlayType():
if (audio.canPlayType("audio/mpeg")){ //進一步處理}
而"probably"和"maybe"都是真值,因此在if語句的條件測試中可以轉換成true。
如果給canPlayType()傳入了一種MIME類型,則返回值很可能是"maybe"或空字符串。這是因為媒體文件本身只不過是音頻或視頻的一個容器,而真正決定文件能否播放的還是編碼的格式。在同時傳入MIME類型和編解碼器的情況下,可能性就會增加,返回的字符串會變成"probably"。下面來看幾個例子。
var audio = document.getElementById("audio-player");//很可能"maybe"if (audio.canPlayType("audio/mpeg")){ //進一步處理}//可能是"probably"if (audio.canPlayType("audio/ogg; codecs=\"vorbis\"")){ //進一步處理}
注意,編解碼器必須用引號引起來才行。下表列出了已知的已得到支持的音頻格式和編解碼器。
元素還有一個原生的JavaScript構造函數(shù)Audio,可以在任何時候播放音頻。從同為DOM元素的角度看,Audio與Image很相似,但Audio不用像Image那樣必須插入到文檔中。只要創(chuàng)建一個新實例,并傳入音頻源文件即可。
var audio = new Audio("sound.mp3");EventUtil.addHandler(audio, "canplaythrough", function(event){ audio.play();});
創(chuàng)建新的Audio實例即可開始下載指定的文件。下載完成后,調用play()就可以播放音頻。
在iOS中,調用play()時會彈出一個對話框,得到用戶的許可后才能播放聲音。如果想在一段音頻播放后再播放另一段音頻,必須在onfinish事件處理程序中調用play()方法。
歷史狀態(tài)管理是現(xiàn)代Web應用開發(fā)中的一個難點。在現(xiàn)代Web應用中,用戶的每次操作不一定會打開一個全新的頁面,因此“后退”和“前進”按鈕也就失去了作用,導致用戶很難在不同狀態(tài)間切換。要解決這個問題,首選使用hashchange事件(第13章曾討論過)。HTML5通過更新history對象為管理歷史狀態(tài)提供了方便。
通過hashchange事件,可以知道URL的參數(shù)什么時候發(fā)生了變化,即什么時候該有所反應。而通過狀態(tài)管理API,能夠在不加載新頁面的情況下改變?yōu)g覽器的URL。為此,需要使用history.pushState()方法,該方法可以接收三個參數(shù):狀態(tài)對象、新狀態(tài)的標題和可選的相對URL。例如:
history.pushState({name:"Nicholas"}, "Nicholas' page", "nicholas.html");
執(zhí)行pushState()方法后,新的狀態(tài)信息就會被加入歷史狀態(tài)棧,而瀏覽器地址欄也會變成新的相對URL。但是,瀏覽器并不會真的向服務器發(fā)送請求,即使狀態(tài)改變之后查詢location.href也會返回與地址欄中相同的地址。另外,第二個參數(shù)目前還沒有瀏覽器實現(xiàn),因此完全可以只傳入一個空字符串,或者一個短標題也可以。而第一個參數(shù)則應該盡可能提供初始化頁面狀態(tài)所需的各種信息。
因為pushState()會創(chuàng)建新的歷史狀態(tài),所以你會發(fā)現(xiàn)“后退”按鈕也能使用了。按下“后退”按鈕,會觸發(fā)window對象的popstate事件 。popstate事件的事件對象有一個state屬性,這個屬性就包含著當初以第一個參數(shù)傳遞給pushState()的狀態(tài)對象。
EventUtil.addHandler(window, "popstate", function(event){ var state = event.state; if (state){ //第一個頁面加載時state為空 processState(state); }});
得到這個狀態(tài)對象后,必須把頁面重置為狀態(tài)對象中的數(shù)據(jù)表示的狀態(tài)(因為瀏覽器不會自動為你做這些)。記住,瀏覽器加載的第一個頁面沒有狀態(tài),因此單擊“后退”按鈕返回瀏覽器加載的第一個頁面時,event.state值為null。
要更新當前狀態(tài),可以調用replaceState(),傳入的參數(shù)與pushState()的前兩個參數(shù)相同。調用這個方法不會在歷史狀態(tài)棧中創(chuàng)建新狀態(tài),只會重寫當前狀態(tài)。
history.replaceState({name:"Greg"}, "Greg's page");
支持HTML5歷史狀態(tài)管理的瀏覽器有Firefox 4+、Safari 5+、Opera 11.5+和Chrome。在Safari和Chrome中,傳遞給pushState()或replaceState()的狀態(tài)對象中不能包含DOM元素。而Firefox支持在狀態(tài)對象中包含DOM元素。Opera還支持一個history.state屬性,它返回當前狀態(tài)的狀態(tài)對象。
HTML5除了定義了新的標記規(guī)則,還定義了一些JavaScript API。這些API是為了讓開發(fā)人員創(chuàng)建出更好的、能夠與桌面應用媲美的用戶界面而設計的。本章討論了如下API。