HTML5 腳本編程

本章內(nèi)容:使用跨文檔消息傳遞、拖放API、音頻與視頻

HTML規(guī)范定義了很多新HTML 標記,為了匹配和這些標記的變化,HTML5規(guī)范也用顯著篇幅定義了很多 JavaScript API。定義這些 API 的用意就是簡化此前實現(xiàn)起來困難重重的任務(wù),最終簡化創(chuàng)建動態(tài) Web 界面工作。

一、跨文檔消息傳遞

跨穩(wěn)定消息傳遞(cross-document messaging)簡稱 XDM。指的是在來自不同域的頁面間傳遞消息。XDM把這種機制規(guī)范化,讓我們能即穩(wěn)妥又簡單地實現(xiàn)跨文檔通信。

XDM的核心是 postMessage() 方法。接受兩個參數(shù)化:一條消息 和 一個表示消息接收方來自哪個域的字符串。第二個參數(shù)對保障安全完全通信非常重要,可以防止瀏覽器把消息發(fā)送到不安全的地方。

// 注意:所有支持 XDM 的瀏覽器也支持 iframe 的contentWindow 屬性
var ifremaWidow = document.getElementById('myframe').contentWidow
ifemaWidow.postMessage('A secret', 'http://www.wrox.com')

如果傳遞給 postMessage() 的第二個參數(shù)是“*”,則可以表示消息發(fā)送給來自任何域的文檔,但我們不推薦這么做

接受 XDM 消息時,會觸發(fā)window 對象的message事件。這個事件是以異步形式觸發(fā)的,因此從發(fā)送消息到接收消息(觸發(fā)接收窗口的 message 事件)可能要經(jīng)過一段時間的延遲。觸發(fā) message 事件后,傳遞給 onmessage 處理程序的事件對象包含以下三方面的重要信息。

  • data:作為 postMessage() 第一個參數(shù)傳入的字符串?dāng)?shù)據(jù)。
  • origin:發(fā)送消息的文檔所在的域,例如:“http://www.wrox.com
  • source:發(fā)送消息的文檔的 window 對象的代理。這個代理對象主要用于在發(fā)送上一條消息的窗口中調(diào)用 postMessage() 方法。如果發(fā)送消息的窗口來自同一個域,那這個對象就是 window。

接受到消息后驗證發(fā)送窗口的來源是至關(guān)重要的,在 onmessage 處理程序中檢測消息來源可以確保傳入的消息來自已知的頁面。
基本的檢查模式如下:

window.onmessage = function(event) {
  event = event || window.event

  // 處理接收到的消息
  processMessage(event.data)

  // 可選:向來源窗口發(fā)送回執(zhí)
  event.source.postMessage('Received', 'http://p2p.wrox.com')
}

event.source 大多情況下只是 window 對象的代理,并非實際的window 對象。不能通過這個代理對象訪問 window 對象的其他任何信息。通過這個代理調(diào)用 postMessage() 就好,這個方法永遠存在,永遠可以調(diào)用。
在通過 內(nèi)嵌框架 加載其它域內(nèi)容的內(nèi)容時,使用XDM 是非常方便的。在混搭(mashup)和社交網(wǎng)絡(luò)應(yīng)用中,這種傳遞消息的方法即為常用。

二、原生拖放

最早啊在網(wǎng)頁中引入 JavaScript 拖放功能的是 IE4。當(dāng)時,網(wǎng)頁中只有兩種對象可以拖放:圖像和某些文本。HTML5以 IE 的實例為基礎(chǔ)制定了拖放規(guī)范。

2.1、拖放事件

拖動某元素時,會依次觸發(fā)下列事件:

  • dragstart
    • 按下鼠標鍵并開始移動鼠標時觸發(fā)
  • drag
    • 在元素被拖動期間會持續(xù)觸發(fā)該事件。
  • dragend
    • 當(dāng)拖動停止(無論是吧元素放到了有效的放置目標,還是放到了無效的放置目標上)

上訴三個事件的目標都是被拖動元素。默認情況下,瀏覽器不會在拖動期間改變被拖動元素的外觀,但你可以自己修改。不過,大多瀏覽器都會為正被拖動的元素創(chuàng)建一個半透明的副本,這個副本始終跟隨著光標移動。

當(dāng)摸一個元素被拖動到一個有效的放置目標上時,下列事件會依次發(fā)生:

  • dragenter
    • 只要有元素拖動到放置目標上,就會觸發(fā)
  • dragover
    • dragenter 之后觸發(fā),在被拖動的元素還在放置目標的范圍內(nèi)移動時,觸發(fā)該事件
  • dragleave 或 drop
    • 如果元素被拖出了放置目標,觸發(fā) dragleave 事件
    • 如果元素放到了放置目標中,則觸發(fā) drop 事件

2.2、自定義放置目標

在拖動元素經(jīng)過某些無效放置目標時,可以看到一種特殊的光標(圓環(huán)中有一條反斜線)表示不能放置。可以把任何元素變成有效的放置目標,方法是重寫 dragenter 和 dragover 事件的默認行為。
例如:假設(shè)有一個ID 為 droptarget 的 <div> 元素,可以用如下代碼將它變成一個放置目標。

var droptarget = document.getElementById('droptarget')

droptarget.ondragover = function(event) {
  event.preventDefault()

}

droptarget.ondragenter = function(event) {
  event.preventDefault()
}

以上代碼執(zhí)行后,你就會發(fā)現(xiàn)當(dāng)拖動著元素移動到放置目標上時,光標變成了允許放置的符號。當(dāng)然,釋放鼠標也會觸發(fā) drop 事件。


在 Firefox 3.5+中,放置事件的默認行為是打開被放置目標上的URL。為了讓 Firefox 支持正常的拖放,還要取消 drop 事件的默認行為,阻止它打開 URL。

droptarget.ondrop = function(event) {
  event.preventDefault()
}

2.3、dataTransfer 對象

為了在拖放操作時實現(xiàn)數(shù)據(jù)交換,IE5 引入了 dataTransfer 對象。它是事件處理對象的屬性,只能在拖放事件處理程序中訪問 dataTransfer 對象。可以使用這個對象的屬性和方法來完善拖放功能。
dataTransfer 對象主要有兩個方法:

  • getDate():取得 setData() 保存的值。
  • setData()

這兩個參數(shù)都接受一個參數(shù):是一個字符串,表示保存的數(shù)據(jù)類型,取值為 "text" 或 "URL",如下表示:

// 設(shè)置和接收文本數(shù)據(jù)
event.dataTransfer.setData("text", "some text")
var text = event.DataTransfer.getData("text")

// 設(shè)置和接收 URL
event.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/rui-list"。dataTransfer 對象可以為每種 MIME 類型都保存一個值。保存在 dataTransfer 對象中的數(shù)據(jù)只能在 drop 事件處理程序中讀取。

在拖動文本框中的文本時,瀏覽器會調(diào)用 setData() 方法,將拖動的文本以“text” 格式保存在 dataTransfer 對象中。作為開發(fā)人員,你也可以正在 dragstart 事件處理程序中調(diào)用 setData(),手工保存自己要傳輸?shù)臄?shù)據(jù),以便將來使用。
Firefox 在其第5個 版本之前不能正確地將“url” 和 “text”映射為 “text/uri-list”和 “text/plain”。但是卻能寶 “Text” 映射為“text/plain”。為了更好地在跨瀏覽器的情況下從 dataTransfer 對象取得數(shù)據(jù),最好在取得 URL 數(shù)據(jù)時檢測兩個值,而在取得文本數(shù)據(jù)時使用“Text”

var dataTransfer = event.datatTransfer

// 讀取 URL
var url = dataTransfer.getData('url') || dataTransfer.getData('text/uri-list')

// 讀取文本
var text = dataTransfer.getData('Text')

2.4、dropEffect 與 effectAllowed

利用 dataTransfer 對象,不光是能夠傳輸數(shù)據(jù),還能通過它來確定被拖動的元素以及作為放置目標的元素 能接接收什么操作。為此,需要訪問 dataTransfer 對象的兩個屬性:dropEffect 和 effectAllowed

通過 dropEffect 屬性可以知道被拖動的元素能夠執(zhí)行哪種放置行為。這個屬性有下列4個可能的值:

  • none:不能把拖動的元素放在這里。這是除文本框之外所有元素的默認值。
  • move:應(yīng)該把拖動的元素移動到放置目標。
  • copy:應(yīng)該把拖動的元素復(fù)制到放置目標。
  • link:表示放置目標會打開拖動的元素(但拖動的元素必須是一個鏈接,有URL)
    在把元素拖動到放置目標上時,以上每一個值都會導(dǎo)致光標顯示為不同的符號,要使用 dropEffect屬性,必須在 ondragenter 事件處理程序中針對放置目標來設(shè)置它

dropEffect 屬性只有搭配 effectAllowed 屬性才有用。effectAllowed 屬性表示允許被拖動元素的哪種 dropEffect,effectAllowed 屬性可能的值如下。

  • uninitialize:沒有給被拖動的元素設(shè)置 任何放置行為。
  • none:被拖動大元素不能有任何行為
  • copy:只允許值為 copy 的dropEffect
  • link:只允許值為 link 的 dropEffect
  • move:只允許值為 move 的 dropEffect
  • copyLink:允許值為 copy 和 link 的 dropEffect
  • copyMove:允許值為 copy 和 move 的 dropEffect
  • linkMove:允許值為 link 和 move 的 dropEffect
  • all:允許任意 dropEffect
    必須在 ondragstart 事件處理程序中設(shè)置 effectAllowed 屬性。

2.5、可拖動

讓其他元素(默認無法拖動的元素)可拖動也是可能的。 HTML5 為所有 HTML 元素規(guī)定了一個 draggable 屬性,表示元素是否可以拖動。圖像和連接的 draggable 屬性自動被設(shè)置成了 true,而其他元素這個屬性的默認值都是 false。

<!-- 讓這個圖像不可以拖動 -->
<img src="smile.gif" draggable="false" alt="Smiley face" />

<!-- 讓這個元素可以拖動 -->
<div draggable="true">...</div>

另外,為了讓 Firefox 支持可拖動屬性,還必須添加一個 ondragstart 事件處理程序,并在 dataTransfer 對象中保存一些信息。

2.6、其他成員

HTML5 規(guī)范規(guī)定 dataTransfer 對象還應(yīng)該包含下列方法 和 屬性。

  • addElement(element):為拖動操作添加一個元素。添加這個元素只能影響數(shù)據(jù)(即增加座位拖動源而響應(yīng)回調(diào)的對象),不會影響拖動操作時頁面元素的外觀。
  • clearData(format):清除以特定格式保存的數(shù)據(jù)。實現(xiàn)這個方法的瀏覽器有 IE、Firefox3.5+、Chrome 和 Safari4+。
  • setDragImage(element, x ,y):指定一副圖像,當(dāng)拖動發(fā)生時,顯示在光標下方。這個方法接受的三個參數(shù)分別是要顯示的HTML 元素和光標在圖像中的x,y坐標。其中,HTML元素可以是一副圖像,也可以是其他元素。是圖像則只顯示圖像,是其他元素則顯示渲染后的元素。實現(xiàn)這個方法的瀏覽器有 Firefox3.5+、Safari4+、Chrome
  • types:當(dāng)前保存的數(shù)據(jù)類型。這是一個類似數(shù)組的集合,以“text”這個的字符串形式保存著數(shù)據(jù)類型。實現(xiàn)這個屬性的瀏覽器有 IE10+、Firefox3.5+、Chrome

三、媒體元素

隨著音頻和視頻在 Web 上的迅速流行,HTML5 新增了兩個與媒體相關(guān)的標簽,讓開發(fā)人員不必依賴任何插件就能在網(wǎng)頁中嵌入瀏覽器的音頻和視頻內(nèi)容。這兩個標簽是 <audio> 和 <video>

<!-- 嵌入視頻 -->
<video src="conference.mpg" id="myVideo">Video player not available. </video>
<!-- 嵌入音頻 -->
<audio src="song.mp3" id="myAudio"> Audio player not available. </audio>

還可以設(shè)置 widthheight 屬性以指定視頻播放器的大小,而為 poster 屬性指定圖像的 URI 可以在加載視頻內(nèi)容期間顯示一副圖像。另外,如果標簽中有 controls 屬性,則意味著瀏覽器應(yīng)該顯示 UI 空間,位于開始和借宿標簽之間的任何內(nèi)容都將作為后備內(nèi)容,在瀏覽器不支持這兩個媒體元素的情況下顯示。

因為并非所有瀏覽器都支持所以媒體格式,所以可以指定多個不同的媒體來源。為此,不用在標簽中指定src屬性,而是要像下面這樣使用一或多個 <source> 元素。

  <!-- 嵌入視頻 -->
  <video id="myVideo">
    <source src="conference.webm" type="video/webm; cpdes='vp8, vorbis'">
    <source src="conference.ogv" type="video/webm; cpdes='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>

3.1、屬性

<video> 和 <audio> 元素都提供了完整的 JavaScript 接口。下表列出了這兩個元素共有的屬性,通過這些屬性可以知道媒體的當(dāng)前狀態(tài)。

屬性 數(shù)據(jù)類形 ???????????????????? 說明
autoplay 布爾值 取得或設(shè)置 autoplay標志
buffered 時間范圍 表示已下載的緩沖的事件范圍的對象
bufferedBytes 字節(jié)范圍 表示已下載的緩沖的字節(jié)范圍的對象
bufferingRate 整數(shù) 下載過程中每秒鐘平均接收到的位數(shù)
bufferingThrottled 布爾值 表示瀏覽器是否對緩沖進行了節(jié)流
controls 布爾值 取得或設(shè)置 controls 屬性,用于顯示或隱藏瀏覽器內(nèi)置的控件
currentLoop 整數(shù) 媒體文件已經(jīng)循環(huán)的次數(shù)
currentSrc 字符串 當(dāng)前播放的媒體文件的URL
currentTime 浮點數(shù) 已經(jīng)播放的秒數(shù)
defaultPlaybackRate 浮點數(shù) 取得或設(shè)置默認的播放速度。默認值為 1.0秒
duration 浮點數(shù) 媒體的總播放事件(秒數(shù))
ended 布爾值 表示媒體文件是否播放完成
loop 布爾值 取得或設(shè)置媒體文件在播放完成后是否再從頭開始播放
muted 布爾值 取得或設(shè)置媒體文件是否靜音
networkState 整數(shù) 表示當(dāng)前媒體的網(wǎng)絡(luò)連結(jié)狀態(tài):0表示空,1表示正在加載,2表示正在加載元數(shù)據(jù),3表示已經(jīng)加載了第一幀,4表示加載完成。
paused 布爾值 表示播放器是否暫停
playbackRate 浮點數(shù) 取得或設(shè)置當(dāng)前的播放速度。用戶可以改變這個值,讓媒體播放速度變快或變慢,這與 defaultPlaybackRate 只能由開發(fā)人員修改的 defaultPlaybackRate 不同
played 時間范圍 到目前為止已經(jīng)播放的事件范圍
readyState 整數(shù) 表示媒體是否已經(jīng)就緒(可以播放了)。0表示數(shù)據(jù)不可用,1表示考科一顯示當(dāng)前怕,2表示可以開始播放,3表示媒體可以從頭到尾播放
seekable 時間范圍 到目前為止已經(jīng)播放的時間范圍
seeking 布爾值 表示播放器是否真正移動到媒體文件中的新位置
src 字符串 媒體文件的來源。任何時候都可以重寫這個屬性
start 浮點數(shù) 取得或設(shè)置媒體文件中開始播放的位置,以秒表示
start 浮點數(shù) 取得或設(shè)置媒體文件中開始播放的位置,以秒表示
totalBytes 整數(shù) 當(dāng)前資源所需的總字節(jié)數(shù)
videoHeight 整數(shù) 返回視頻(不一定是元素)的高度。只適用于 <video>
videoWidth 整數(shù) 返回視頻(不一定是元素)的寬度。只適用于 <video>
volume 浮點數(shù) 取得或設(shè)置當(dāng)前音量,值為 0.0 到1.0

其中很多屬性也可以直接在 <audio> 和 <video> 元素中設(shè)置

3.2、事件

處理大量屬性之外,這兩個媒體云阿蘇還可以觸發(fā)很多事件。這些事件監(jiān)控著不同的屬性的變化,這些變化可能是媒體播放的結(jié)果,也可能是用戶操作播發(fā)器的結(jié)果。下表列出了媒體元素相關(guān)的事件。

事件 觸發(fā)時機
abort 下載中斷
canplay 可以播放是;readyState值為2
canplaythrough 播放可繼續(xù),而且應(yīng)該不會中斷;readyState值為3
canshowcurrentframe 當(dāng)前幀已經(jīng)下載完成;readyState值為1
dataunavailable 當(dāng)前沒有數(shù)據(jù)而不能播放;readyState 值為 0
durationchange duration 屬性的值改變
emptied 網(wǎng)絡(luò)連接關(guān)閉
empty 發(fā)送錯誤阻止了媒體下載
ended 媒體已播放到末尾,播放停止
error 下載期間發(fā)生網(wǎng)絡(luò)錯誤
load 所有媒體已加載完成。這個事件可能會被廢棄,建議使用 canplaythrough
loadeddate 媒體的第一幀以加載完成
loadedmetadata 媒體的元數(shù)據(jù)已加載完成
loadstart 下載已開始
pause 播放已暫停
play 媒體已接收到指令開始播放
playing 媒體已實際開始播放
progress 正在下載
ratechange 播放媒體的速度改變
seeked 搜索結(jié)束
seeking 正移動到新位置
stakked 瀏覽器嘗試下載,但未接收到數(shù)據(jù)
timeupdate currentTime被以不合理或意外的方式更新
volumechange volume 屬性值或 muted屬性值已改變
waiting 播放暫停,等待下載更多數(shù)據(jù)

這些事件之所以如此具體,就是為了讓開發(fā)人員只使用少量 HTML 和 JavaScript(與創(chuàng)建 Flash 影片相比)即可編寫出自定義的 音頻/視頻播放器。

3.3、自定義媒體播放器

使用 <audio> 和 <video> 元素的 play() 和 pause() 方法,可以手工控制媒體文件的播放。組合使用屬性、事件和這兩個方法,很容易可以創(chuàng)建一個自定義的媒體播放器。

  <div class="mediaplayer">
    <div class="video">
      <video src="./video.mp4" poster="videoPoster.png" width="300" height="200" id="player">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>
<script>
  // 取得元素的引用
  var player = document.getElementById('player'),
      btn = document.getElementById('video-btn'),
      curtime = document.getElementById('curtime'),
      duration = document.getElementById('duration')

  
  player.oncanplaythrough = function(event) { // 媒體文件加載完成

      // 更新播放時間
    duration.innerHTML = player.duration

    // 為按鈕添加事件處理程序
    btn.onclick = function(event) {
      console.log(player.paused)
      if (player.paused) {
        player.play()
        btn.value = 'Pause'
      } else {
        player.pause()
        btn.value = 'Play'
      }
    }

    // 定時更新當(dāng)前時間
    setInterval (function () {
      curtime.innerHTML = player.currentTime
    }, 250)
  }

3.4、檢測編解碼器的支持情況

并非所有瀏覽器都支持 <video> 和 <audio> 的所有編解碼器,而這基本上就意味著你必須提供多個媒體來源。不過,也有一個 JavaScript API 能夠檢測瀏覽器是否支持某種格式和編輯器。這兩個媒體元素都有一個 canPlayType() 方法,該方法接收一種格式/編解碼字符串,返回“probably”、“maybe” 或 “”(空字符串)。

if (audio.canPlayType("audio/mpeg") {

}

如果給 canPlayType() 傳入了一種 MIME 類型,則返回值可能是 "maybe" 或空字符串。這就是 因為媒體文件本身只不過是 音頻或視頻的一個容器,而真正決定文件能否播放的還是編碼的格式。在同時傳入 MIME 類型和編解碼器的情況下,可能性就會增加,返回的字符串會變成"probably"。

var audio = dcoument.getElement('audio-player')

// 很有可能 "maybe"
if (audio.canPlayType('audio/mpeg') {
  // todo
}

// 可能是 probably
if (audio.canPlayType('audio/ogg; codecs="vorbis"')) {
  // todo
}

下標列出了已得到支持的音頻格式和編解碼器

音頻 字符串 支持的瀏覽器
AAC audio/map4; codecs="mp4a.40.2" IE9+、Safari4+、iOS版Safari
MP3 audio/mpeg IE9+、Chrome
Vorbis audio/ogg; codecs="vorbis" Firefox3.5+、Chrome、Opera 10.5+
WAV audio/wav; codecs="1" Firefox3.5+、Opera 10.5+、Chrome

當(dāng)然也可以使用 canPlayType() 來檢測視頻格式。下表列出了已知的得到支持的音頻格式和編解碼器

視頻 字符串 支持的瀏覽器
H.264 video/mp4; codecs="avc1.42E01E, mp4a.40.2 IE9+、Safari4+、iOS版Safari、Android版WebKit
Theora video/ogg; codecs="theora" Firefox3.5+、Opera10.5、Chrome
WebMvideo/webm; codecs="vp8, borbis" Firefox4+、Opera10.6、Chrome

3.5、Audio類型

<audio> 元素還有一個原生的 JavaScript 構(gòu)造函數(shù) Audio,可以在任何時候播放音頻。從同為DOM元素的角度來看,Audio 和 Image 很相似,但 Auido 不用像 Image 那樣必須插入到文檔中,只要創(chuàng)建一個示例,賓川如音頻源文件即可。

var audio = new Audio('sound.mp3')
audio.oncanplaythrough = function(event) {
  audio.play()
}

創(chuàng)建新的 audio 實例即可開始下載指定的文件,下載完成后,調(diào)用 play() 就可以播放音頻。

四、歷史狀態(tài)管理

歷史狀態(tài)管理是現(xiàn)代Web 應(yīng)用 開發(fā)的一個難點。在Web應(yīng)用中,用戶每次操作不一定會打開一個全新的頁面,因此“后退”和“前進”按鈕也就失去了作用,導(dǎo)致用戶很難在不同狀態(tài)間切換。要解決這個問題,首先使用 hashchange 事件。HTML5 通過更新 history 對象為管理歷史狀態(tài)提供了方便

通過 hashchange 事件,可以知道 URL的參數(shù)什么時候發(fā)生了變化,即什么時候該有所反應(yīng)。而通過狀態(tài)管理 API,能夠在不加載新頁面的情況下改變?yōu)g覽器的URL。為此,需要使用 history.pushState() 方法,該方法接三個參數(shù):狀態(tài)對象、新狀態(tài)的標題、可選的相對URL。

history.pushState({name: 'Lee'}, 'Lee page', 'Lee.html')

執(zhí)行 pushState() 方法后,新的狀態(tài)信息就會被加入歷史狀態(tài)棧,而瀏覽器地址欄也會變成新的相對URL。


因為 pushState() 會創(chuàng)建新的歷史狀態(tài),所以你會發(fā)現(xiàn)“后退”按鈕也能使用了。按下“后退”按鈕,會觸發(fā) window 對象的 popstate 事件。popstate 事件的事件對象有一個 state 屬性,這個數(shù)據(jù)就包含著當(dāng)初以第一個參數(shù)傳遞給 pushState() 的狀態(tài)對象。


window.onpopstate = function(event) {
  var state = event.state
  if (state) { // 第一個頁面加載時 state 為空
    processState(state)
  }
}

要更新當(dāng)前狀態(tài),可以調(diào)用 replaceState(),傳入的參數(shù)與 pushState() 的前兩個參數(shù)相同。調(diào)用這個方法不會在歷史狀態(tài)棧中創(chuàng)建新狀態(tài),只會重寫當(dāng)前狀態(tài)。

history.replaceState({name: "Greg"}, "greg's page")

五、小結(jié)

  • 跨文檔消息傳遞 API 能讓我們在不降低同源策略安全性的前提下,在來自不同域的文檔間傳遞消息。
  • 原生拖動功能讓我們可以方便的指定某個元素可拖動,并在操作系統(tǒng)要放置時做出響應(yīng),還可以創(chuàng)建自定義的可拖動元素及放置目標。
  • 媒體元素 <audio> 和 <video> 擁有自己的與音頻和視頻交互的API。并非所有瀏覽器支持所有的媒體格式,因此應(yīng)該使用 canPlayType() 檢測瀏覽器是否支持特定的格式。
  • 歷史狀態(tài)管理讓我們不必卸載當(dāng)前頁面即可修改瀏覽器的歷史狀態(tài)棧。有了這種機制,用戶就可以通過“后退” 和 “前進” 按鈕在頁面狀態(tài)間切換,而這些狀態(tài)完全由 JavaScript 進行控制。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容