JS红皮书读书笔记-16-HTML5脚本编程

TOC
  1. 1. 跨文档消息传递(XDM)
  2. 2. 原生拖放
    1. 2.1. 拖放事件
    2. 2.2. 自定义放置目标
    3. 2.3. dataTransfer对象
    4. 2.4. dropEffect与effectAllowed
    5. 2.5. 可拖动
    6. 2.6. 其他成员
  3. 3. 媒体元素
    1. 3.1. 属性
    2. 3.2. 事件
    3. 3.3. 自定义媒体播放器
    4. 3.4. 检测编解码器的支持情况
    5. 3.5. Audio类型
  4. 4. 历史状态管理

跨文档消息传递(XDM)

跨文档消息传递(cross-document messaging)指的是在来自不同域的页面间传递消息。例如,www.wrox.com域中的页面与位于一个内嵌框架中的p2p.wrox.com域中的页面通信。

XDM的核心是postMessage()方法。对于XDM而言,就是将信息发送至包含在当前页面中的iframe元素,或者由当前页面弹出的窗口。
这个方法接受两个参数,一个消息字符串和一个表示消息接受方来自哪个域的字符串。如果内嵌框架的来源不符合参数,则什么也不做,传递“*”代表匹配所有文档。

var iframeWindow = document.getElementById("myframe").contentWindow; 
iframeWindow.postMessage("A secret", "http://www.wrox.com");

原生拖放

拖放事件

通过拖放事件,可以控制拖放相关的各个方面,其中最关键的地方在于确定那里发生了拖放事件,有些事件是在被拖动的元素上产生的,有些是在放置目标上触发的。
拖动某元素时将依次在被拖动的元素上触发下列事件:

  • dragstart:按下鼠标且鼠标移动开始时
  • drag:在元素被拖动的过程中持续触发
  • dragend:当拖动停止时,无论把元素放到有效的放置目标上还是无效的上,都会触发dragend事件。

在拖动的过程中,被拖动的元素的外观是可以改变的,一般浏览器会默认创建一个半透明的副本,这个副本始终跟随光标移动。
当某个元素被放置到有效的放置目标的时候,下列事件会在放置目标会依次发生:

  • dragenter:元素被拖动到放置目标上,就回触发一次dragenter
  • dragover:元素在放置目标上继续被拖动时,会持续触发这个事件
  • dragleave或drop:如果元素又被拖离了目标范围,触发dragleave,dragover事件不再触发,如果直接放置在了目标中,会触发drop事件。

自定义放置目标

所有元素都支持放置目标事件,但有些元素是默认不允许放置的,如果拖动元素经过不允许放置的的元素,是不会触发drop事件的,重写其dragenter和dragover事件可以使其变为可放置的:

EventUtil.addHandler(dropDiv, "dragover", function(event){
EventUtil.preventDefault(event);
});
EventUtil.addHandler(dropDiv, "dragenter", function(event){
EventUtil.preventDefault(event);
});
EventUtil.addHandler(dropDiv, "drop", function(event){
alert("droped");
});

dataTransfer对象

为了在拖放操作时实现数据的交换,引入了dataTransfer对象(25章也有这个示例),这是事件对象的一个属性,这个对象有两个方法:getData()和 setData()。这两个方法都需要一个代表数据类型的参数,在HTML5中,这个是MIME类型,为了向后兼容,还可以是”text”和”URL”,只不过他们其实是被映射为MIME类型”text/plain”和”text/uri-list”。setData还需要一个对应的数据作为参数。在这个对象中,对不同的MIME可以同时存储多个值。
这个对象只在drop事件中读取。
setData在拖动开始时设置,拖动文本,链接或图像时,浏览器会自动调用这个方法保存文字或URL。我们自己也可以在dragstart事件中调用来保存我们自己的数据。
getData在drop事件中调用,获取相关数据。

event.dataTransfer.setData("URL", "http://www.wrox.com/");
var url = dataTransfer.getData("url")||dataTransfer.getData("text/uri-list");

dropEffect与effectAllowed

利用dataTransfer对象,不光能传送数据,还能确定被拖动元素以及作为放置目标的元素能够接收什么操作。
dropEffect属性可以知道被拖动元素能执行哪种放置行为:

  • none
  • move
  • copy
  • link
    这个属性要在开始拖动ondragstart时设置

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

  • uninitialized
  • none
  • copy
  • link
  • move
  • copyLink
  • copyMove
  • linkMove
  • all

这个也要在ondragstart时设置

可拖动

<div draggable="true">...</div>

其他成员

HTML5规范规定dataTransfer对象还有下列方法和属性:

  • addElement(element)
  • clearData(format)
  • setDragImage(element, x, y)
  • types

媒体元素

新增audio /video标签

属性

事件

自定义媒体播放器

其实就是利用pause/play/currentTime等相关属性方法来封装一个播放器

检测编解码器的支持情况

利用canPlayType方法来检测是否支持某种MIME类型的媒体:

if(audio.canPlayType('audio/mpeg')){ //返回'probably'/'maybe'、'' 三个值之一
//...
}

Audio类型

audio类型有一个元素JS的构造函数Audio,可以在任何时候播放音频, 并且: 通过 new Audio创建的实例不必插入到文档中就可以播放.

历史状态管理

在现在的Web应用中,用户的每次操作并不一定会打开一个新的页面,前进和后退按钮在这里也就失去了作用。HTML5通过更新history对象为管理历史状态提供了方便。

hashchange事件可以知道URL的参数什么时候发生了变化,这时使用history.pushState()可以在不加载新页面的情况下改变浏览器的URL,该方法接收3个参数:状态对象,新状态的标题和可选的相对URL。

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

这个方法执行后,新的状态会被加入历史状态栈,浏览器的地址栏也会变成新的相对URL。但其实并没有像服务器发送数据。其中的第一个参数是用来初始化这个页面的数据用的。

这时后退按钮就能使用了,这时点击后退按钮会触发window对象的popstate事件,这个事件有个属性叫state,就是pushState的第一个参数。回到上一个页面,读取上一个页面的state来初始化上一个页面。比如你回到的是nicholas.html,那你读到的state的name就是Nicholas。
浏览器加载的第一个页面木有状态,其state是null。
还有个方法是replaceState()这个方法接收pushState的前两个参数,重写当前状态,不在历史栈中创建新状态。

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

这时以后再返回这个页面读到的state.name就是Greg了。
要注意,push进去的每个状态服务器上都要有个真的页面,要不一刷新就404了。
按照逻辑这个pushState应该是在每个web页面刚加载时就push进去,把初始化这个页面的每个数据一起push进去。在当前页面如果有什么即时的修改在下次进入这个页面也该体现的,就使用replaceState。


本章完

访客评论