《JavaScript高级程序设计》笔记:HTML5脚本编程(16)
跨文档消息传递
跨文档消息传递(cross-document messaging),有时候简称为XDM,指的是在来自不同域的页面间传递消息。例如,www.wrox.com域中的页面与位于一个内嵌框架中的p2p.wrox.com域中的页面通信。
XDM的核心是postMessage()方法。在HTML5规范中,除了XDM部分之外的其他部分也会提到这个方法名,但都是为了同一个目的:向另一个地方传递数据。对于XDM而言,“另一个地方”指的是包含在当前页面中的<iframe>元素,或者由当前页面弹出的窗口。
postMessage()方法接收两个参数:一条消息和一个表示消息接收方来自哪个域的字符串。第二个参数对保障安全通信非常重要,可以防止浏览器把消息发送到不安全的地方。
//注意所有支持XDM的浏览器也支持iframe的contentWindow属性
var iframeWindow = document.getElementById("myframe").contentWindow;
iframeWindow.postMessage("A secret","http://www.wrox.com");
最后一行代码尝试向内嵌框架中发送一条消息,并指定框架中的文档必须来源于http:www.wrox.com域。如果来源匹配,消息会传递到内嵌框架中;否则,postMessage()什么也不做。如果传给postMessage()的第二个参数是“*”,则表示可以把消息发送给来自任何域的文档,但我们不推荐这样做。
接收到XDM消息时,会触发window对象的message事件。这个事件是以异步形式触发的,因此,从发送消息到接收消息(触发接收窗口的message事件)可能要经过一段时间的延迟。触发message事件后,传递给onmessage处理程序的事件对象包含以下三方面的重要信息。
- data:作为postMessage()第一个参数传入的字符串数据。
- origin:发送消息的文档所在的域,例如"http://www.wrox.com"。
- source:发送消息的文档的window对象的代理。这个代理对象主要用于在发送上一条消息的窗口中调用postMessage()方法。如果发送消息的窗口来自同一个域,那这个对象就是window。
window.addEventListener("message",function(event){
if(event.origin == 'http://www.wrox.com'){
//处理接收到的数据
processMessage(event.data); //可选:向来源窗口发送回执
event.source.postMessage("Received!","http://p2p.wrox.com");
}
},false);
XDM还有一些怪异之处。postMessage()的第一个参数最早是作为“永远都是字符串来实现的”,但后来改变了可以使用任意结构了。并非所有浏览器都支持任意结构,所以最好还是传入字符串,即在要传递数据之前调用JSON.stringify()方法,然后在onmessage事件处理程序中调用JSON.parse()。
原生拖放
拖动事件
拖动某元素时,将依次触发下列事件:
- (1)dragstart
- (2)drag
- (3)dragend
上述三个事件的目标都是被拖动的元素。
当某个元素被拖动到一个有效的放置目标上时,下列事件会依次执行:
(1)dragenter
(2)dragover
(2)dragleave或drop
只要有元素被拖动到放置目标上,就会触发dragenter事件(类似于mouseover事件)。紧随其后的是dragover事件,而且在被拖动的元素还在放置目标的范围内移动时,就会持续触发该事件。如果元素被拖出了放置目标,dragover事件就不再发生,但会触发dragleave事件(类似于mouseout事件)。如果元素被放到了放置目标中,则会触发drop事件而不是dragleave事件。上述三个事件的目标都是作为放置目标的元素。
自定义放置目标
在拖动元素经过某些无效放置目标时,可以看到一种特殊的光标(圆环中有一条反斜线),表示不能放置。虽然所有元素都支持放置目标事件,但这些元素默认是不允许放置的。如果拖动元素经过不允许放置的元素,无论用户如果操作,都不会发生drop事件。不过,你可以把任何元素变成有效的放置目标,方法是重写dragenter和dragover事件的默认行为。例如,假设有一个ID为“droptarget”的<div>元素,可以用如下代码将它变成一个放置目标。
var droptarget = document.getElementById("droptarget");
EventUtil.addHandler(droptarget,"dragover",function(){
EventUtil.preventDefault(event);
});
EventUtil.addHandler(droptarget,"dragenter",function(){
EventUtil.preventDefault(event);
以上代码执行后,你就会发现当拖动着元素移动到放置目标上时,光标变成了允许放置的符号。当然,释放鼠标也会触发drop事件。
在Firefox3.5中,放置事件的默认行为是打开被放到放置目标上的URL。换句话说,如果是把图像拖动到放置目标上,页面就会转向图像文件;而如果是把文本拖放到放置目标上,则会导致无效URL错误。因此,为了让Firefox支持正常的拖放,还要取消drop事件的默认行为,阻止它打开URL:
EventUtil.addHandler(droptarget,"drop",function(){
EventUtil.preventDefault(event);
});
dataTransfer对象
dataTransfer对象是事件对象的一个属性,用于从被拖动元素向放置目标传递字符串格式的数据。因为他是事件对象的属性,所以只能在拖动事件的事件处理程序中访问dataTransfer对象。
dataTransfer对象有两个主要的方法:getData()和setData()。getData()可以取得由setData()保存的值。setData()方法的第一个参数,也是getData()方法唯一的一个参数,是一个字符串,表示保存的数据类型,取值为“text”或“URL”,如下代码:
//设置和接收文本数据
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");
IE只定义了“text”和“URL”两种有效的数据类型,而HTML5则对此加以扩展,允许指定各种MIME类型。考虑到向后兼容,HTML5也支持“text”和“URL”,但这两种类型会被映射为“text/plain”和“text/url-list”。
实际上,dataTransfer对象可以为每种MIME类型都保存一个值。换句话说,同时在这个对象中保存一段文本和一个URL不会有任何问题。不过,保存在dataTransfer对象的数据只能在drop事件处理程序中读取。如果在ondrop处理程序中没有读到数据,那就是dataTransfer对象已经被被销毁了,数据也丢失了。
Firfox在其第五个版本之前不能将"URL"和“text”映射为“text/url-list”和“text/plain”,但却能把“Text”映射为“text/plain”,为了更好的兼容浏览器,可使用如下代码:
var dataTransfer = event.dataTransfer;
//读取URL
var url = dataTransfer.getData('url') || dataTransfer.getData("text/url-list");
//读取文本
var text = dataTransfer.getData("Text");
注意:一定要把短数据类型放到前面,因为IE10以及之前的版本不支持扩展的MIME类型,而他们在遇到无法识别的数据类型时,会抛出错误。
dropEffect和effectAllowed
其中,通过dropEffect属性可以知道被拖动的元素能够执行哪种放置行为。这个属性有4个可能的值。
- none:不能把拖动的元素放在这里。这是除文本框之外所有元素的默认值。
- move:应该把拖动的元素移动到放置目标。
- copy:应该把拖动的元素复制到放置目标。
- link:表示放置目标会打开拖动的元素(但拖动的元素必须是一个链接,有URL)。
要使用dropEffect属性,必须在ondragenter事件处理程序中针对放置目标来设置它。
dropEffect属性只有搭配effectAllowed属性才有用。effectAllowed属性表示允许拖动元素的哪种dropEffect。effectAllowed属性有以下可能的值:
- uninitialized:没有给被拖动的元素设置任何放置行为。
- 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事件处理程序中设置effectAllowed属性。
可拖动
默认情况下,图像、链接、文本是可以拖动的,文本只有在被选中的情况下才能拖动,而图像和链接在任何时候都可以拖动。
让其它元素可以拖动,HTML5为所有的HTML元素规定了一个draggable属性。
<!--让图像不可拖动-->
<img src="data:images/avatar.png" draggable="false"/> <!--让这个元素可以拖动-->
<div draggable="true">可拖动的元素</div>
其它成员
HTML5规范规定dataTransfer对象还有下列属性和方法:
- addElement(element):为拖动操作添加一个元素。添加这个元素只影响数据(即增加作为拖动源而响应回调的对象),不会影响拖动操作时页面元素的外观。
- clearData(format):清除以特定格式保存的数据。
- setDragImage(element,x,y):指定一副图像,当拖动发生时,显示在光标下方。这个方法接收的三个参数分别为要显示的HTML元素和光标在图像中的x、y坐标。其中,HTML元素可以是一副图像,也可以是其它元素。
- types:当前保存的数据类型。这是一个类似数组的集合,以“text”这样的字符串形式保存着数据类型。
媒体元素
<audio>和<video>
《JavaScript高级程序设计》笔记:HTML5脚本编程(16)的更多相关文章
- JavaScript高级程序设计笔记(一)
---恢复内容开始--- 前三章为基础知识,为了方便以后查看,所以比较啰嗦.这里对函数的基本操作没有记录. 1.JavaScript的实现 虽然 JavaScript 和 ECMAScript 通常都 ...
- JavaScript高级程序设计笔记之面向对象
说起面向对象,大部分程序员首先会想到 类 .通过类可以创建许多具有共同属性以及方法的实例或者说对象.但是JavaScript并没有类的概念,而且在JavaScript中几乎一切皆对象,问题来了,Jav ...
- javascript高级程序设计--笔记01
概述 JavaScript的实现包含三个部分: 1 核心(ECMAScript) 提供核心语言功能 2 文档对象模型(DOM) 一套提供了访问以及操作网页内容的API 3 浏览器对象模型( ...
- JavaScript高级程序设计之动态脚本及动态样式
1.动态加载脚本(src 原理,异步,支持跨域) var loadScript = function (url, callback) { var script = document.createEle ...
- <javascript高级程序设计>笔记
1.要讲一个值转换成其对应的Boolean类型 ,可以调用转型函数Boolean(). var message=“hello world!”; var messageAsBoolean=Boolean ...
- javascript事件小结(事件处理程序方式)--javascript高级程序设计笔记
1.事件流:描述的是从页面中接收事件的顺序. 2.事件冒泡:IE的事件流叫做事件冒泡,即事件开始从具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到不具体的节点(文档). 3.事件捕获 ...
- javaScript高级程序设计笔记 1
核心 ECMAScript 文档对象模型 DOM 浏览器对象模型 BOM 延迟脚本 defer typeof操作符 判断字符类型 返回 undefined boolean s ...
- JavaScript高级程序设计--表单脚本
1.提交表单 submit onsubmit 2.表单的change事件 input与textarea元素的change事件触发在,他们失去焦点且value值改变的时候 select的change ...
- JavaScript高级程序设计笔记 事件冒泡和事件捕获
1.事件冒泡 要理解事件冒泡,就得先知道事件流.事件流描述的是从页面接收事件的顺序,比如如下的代码: <body> <div> click me! </div> & ...
- javaScript高级程序设计笔记 2
Undefinde Null Boolean Number String 基本类型 Object 引用类型 只有引用类型才能动态的添加属性 赋值基本类型和引用类型也不相同,复制的基本类型的 ...
随机推荐
- Spring Boot 定义系统启动任务,你会几种方式?
在 Servlet/Jsp 项目中,如果涉及到系统任务,例如在项目启动阶段要做一些数据初始化操作,这些操作有一个共同的特点,只在项目启动时进行,以后都不再执行,这里,容易想到web基础中的三大组件( ...
- 目标检测 anchor 理解笔记
anchor在计算机视觉中有锚点或锚框,目标检测中常出现的anchor box是锚框,表示固定的参考框. 目标检测的任务: 在哪里有东西 难点: 目标的类别不确定.数量不确定.位置不确定.尺度不确定 ...
- 小步快跑的公司可以最简化操作直接通过log4net将日志写入ElasticSearch
很多小步快跑的公司,开发人员多则3-4个,面对巨大业务压力,日连夜的赶着上线,快速试错,自然就没时间搭建一些基础设施,比如说logCenter,但初期 项目不稳定,bug又多,每次都跑到生产去找日志 ...
- 委托与lambda关系
什么是委托委托是没有方法体的,声明委托就是一个关键字: delegate ,委托可以试有参无参,有返回值无返回值.和我们的方法是一样的.不同的区别是 委托没有方法体的,委托可放在类下也可以放在类的外面 ...
- 2018-09-15 Java源码英翻中库以及服务原型
服务很简单, 只为演示这个库, 源码在: program-in-chinese/code_translator_service. 在Postman测试效果: 演示服务地址: 74.91.17.250: ...
- Windows Cluster 添加新节点--验证报错
今天给既有Windows Cluster 添加节点时,验证总是不通过.报错信息为 防火墙未正确配置为故障转移群集.现将处理步骤汇总如下. 1.错误具体信息 报错的位置 --[验证警告] 的步骤中发现错 ...
- Abnormal build process termination--解决IDEA启动web项目报错
iDEA启动后报Error:Abnormal build process terminatio 报错的原因如下: Error:Abnormal build process termination: & ...
- #001 Python 00号作业:关于课程
请大家继续思考,你希望我们的课程主要涉略哪些方面?你希望我们的课程能够带给你哪些基本的技能?你希望理论课应该怎么上,实验课应该怎么上?对于我们的课程有什么建议或意见 作为一名计算机专业的学生,对于py ...
- Java地位被撼动?Java与JavaScript的趣事连载
第一回 JavaScript的进攻 公元2014年,Java 第八代国王终于登上了王位. 第一次早朝,国王坐在高高的宝座上,看着毕恭毕敬的大臣,第一次体会到了皇权的威力. 德高望重的IO大臣颤悠悠地走 ...
- Fork/Join框架详解
Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架.Fork/Join框架要完成两件事情: 1.任务分 ...