第 16 章 HTML5 脚本编程

61 阅读4分钟

16.1 跨文档消息传递

跨文档消息传送(cross-document messaging),有时候简称为 XDM,指的是在来自不同域的页面间传递消息。

XDM 的核心是 postMessage()方法。对于 XDM 而言,“另一个地方”指的是包含在当前页面中的<iframe>元素,或者由当前页面弹出的窗口。

postMessage()方法接收两个参数,一条消息和一个表示消息接收方来自哪个域的字符串。

//注意:所有支持 XDM 的浏览器也支持 iframe 的 contentWindow 属性
var iframeWindow = document.getElementById("myframe").contentWindow;
iframeWindow.postMessage("A secret", "http://www.wrox.com");

接收到 XDM 消息时,会触发 window 对象的 message 事件。这个事件是以异步形式触发的。触发 message 事件后,传递给 onmessage 处理程序的事件对象包含以下三方面的重要信息。

  • data:作为 postMessage()第一个参数传入的字符串数据。
  • origin:发送消息的文档所在的域,例如"www.wrox.com"。
  • source:发送消息的文档的 window 对象的代理。

16.2 原生拖放

16.2.1 拖放事件

拖动某元素时,将依次触发下列事件:

  1. dragstart
  2. drag
  3. dragend

当某个元素被拖动到一个有效的放置目标上时,下列事件会依次发生:

  1. dragenter
  2. dragover
  3. dragleave 或 drop

16.2.2 自定义放置目标

如果拖动元素经过不允许放置的元素,无论用户如何操作,都不会发生 drop 事件。你可以把任何元素变成有效的放置目标,方法是重写 dragenter 和 dragover 事件的默认行为。

16.2.3 dataTransfer对象

为了在拖放操作时实现数据交换,引入了dataTransfer 对象,它是事件对象的一个属性,用于从被拖动元素向放置目标传递字符串格式的数据。因为它是事件对象的属性,所以只能在拖放事件的事件处理程序中访问 dataTransfer 对象。

dataTransfer 对象有两个主要方法:getData()和 setData()。

//设置和接收文本数据
event.dataTransfer.setData("text", "some text");
var text = event.dataTransfer.getData("text");

//设置和接收 URL
event.dataTransfer.setData("URL", "http://www.wrox.com/");
var url = event.dataTransfer.getData("URL");

16.2.4 dropEffect与effectAllowed

利用 dataTransfer 对象,还能通过它来确定被拖动的元素以及作为放置目标的元素能够接收什么操作。为此,需要访问 dataTransfer 对象的两个属性:dropEffect 和 effectAllowed。

通过 dropEffect 属性可以知道被拖动的元素能够执行哪种放置行为。

effectAllowed 属性表示允许拖动元素的哪种 dropEffect

16.2.5 可拖动

文本只有在被选中的情况下才能拖动,而图像和链接在任何时候都可以拖动。HTML5 为所有 HTML 元素规定了一个 draggable 属性,表示元素是否可以拖动。

<!-- 让这个图像不可以拖动 -->
<img src="smile.gif" draggable="false" alt="Smiley face">

<!-- 让这个元素可以拖动 -->
<div draggable="true">...</div>

16.3 媒体元素

HTML5 新增了两个与媒体相关的标签,<audio>和<video>。

<!-- 嵌入视频 -->
<video src="conference.mpg" id="myVideo">Video player not available.</video>

<!-- 嵌入音频 -->
<audio src="song.mp3" id="myAudio">Audio player not available.</audio>

16.3.1 属性

<video>和<audio>元素都提供了完善的 JavaScript 接口。

16.3.2 事件

除了大量属性之外,这两个媒体元素还可以触发很多事件。这些事件监控着不同的属性的变化,这些变化可能是媒体播放的结果,也可能是用户操作播放器的结果

部分常用事件

abort  下载中断
canplay  可以播放时;readyState值为2
ended  媒体已播放到末尾,播放停止
load  所有媒体已加载完成。这个事件可能会被废弃,建议使用canplaythrough
loadeddata  媒体的第一帧已加载完成
pause  播放已暂停
play  媒体已接收到指令开始播放
playing  媒体已实际开始播放
volumechange  volume属性值或muted属性值已改变
waiting  播放暂停,等待下载更多数据

16.3.3 自定义媒体播放器

使用<audio>和<video>元素的 play()和 pause()方法,可以手工控制媒体文件的播放。

16.3.4 检测编解码器的支持情况

使用canPlayType()方法来检测是否支持某种格式和编解码器,该方法接收一种格式/编解码器字符串,返回"probably"、"maybe"或""(空字符串)。

var audio = document.getElementById("audio-player");
//很可能"maybe"
if (audio.canPlayType("audio/mpeg")){
//进一步处理
}

//可能是"probably"
if (audio.canPlayType("audio/ogg; codecs=\"vorbis\"")){
//进一步处理
}

16.3.5 Audio类型

<audio>元素还有一个原生的 JavaScript 构造函数 Audio,可以在任何时候播放音频。

var audio = new Audio("sound.mp3");
audio.# addEventListener("canplaythrough", function(event){
    audio.play();
});

16.4 历史状态管理

HTML5 通过更新 history 对象为管理历史状态提供了方便。通过状态管理 API ,能够在不加载新页面的情况下改变浏览器的 URL 。

history.pushState()方法,该方法可以接收三个参数:状态对象、新状态的标题和可选的相对 URL。

history.pushState({name:"Nicholas"}, "Nicholas' page", "nicholas.html");

history.replaceState()方法,传入的参数与 pushState()的前两个参数相同。调用这个方法不会在历史状态栈中创建新状态,只会重写当前状态。