16.1 跨文档消息传递
postMessage():接收两个参数:一条消息和一个表示消息接收方来自哪个域的字符串
传递给 onmessage 处理程序的事件对象包含以下三方面的重要信息。
data:作为 postMessage()第一个参数传入的字符串数据;
origin:发送消息的文档所在的域,例如"http://www.wrox.com";
source:发送消息的文档的 window 对象的代理。这个代理对象主要用于在发送上一条消息的 窗口中调用 postMessage()方法。如果发送消息的窗口来自同一个域,那这个对象就是 window。
//父页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面一</title>
</head>
<body>
<h2 id="h2">页面一</h2>
<a href="1.html" target="iframe">页面二</a>
<button type="button">改变页面二按钮颜色</button>
<hr>
<iframe id="iframe" src="1.html" name="iframe" frameborder="0" scrolling="no">您的浏览器不支持iframe</iframe>
<script>
window.onload=function(){
var otherWindow=document.getElementsByTagName("iframe")[0].contentWindow;
console.log(otherWindow)
//为保险起见,使用 postMessage()时,最好还是只传字符串。如果你想传入结构化的数据,最佳选择是先在要传入的数据上调用 JSON.stringify(),通过 postMessage()传入得到的字符串,然 后再在 onmessage 事件处理程序中调用 JSON.parse()
otherWindow.postMessage('Heollow', 'http://localhost:90');//*表示所有的域名
}
//接收回执的值
window.addEventListener("message", function receiveMessage(event){
console.log(event.data)
}, false);
</script>
</body>
</html>
//子页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面二</title>
</head>
<body>
<div class="box">
hello world !
<button id="btn" type="button">改变页面一h2颜色</button>
</div>
<script>
window.addEventListener("message", function receiveMessage(event){
var origin = event.origin;
if (origin !== "hhttp://localhost:90") return;
alert(1)
console.log(event.data)
//向来源窗口发送回执
event.source.postMessage("Received!", "*");
}, false);
//EventUtil.addHandler(window, "message", function(event){
//确保发送消息的域是已知的域
//if (event.origin == "http://www.wrox.com"){
//处理接收到的数据 processMessage(event.data);
//可选:向来源窗口发送回执
//event.source.postMessage("Received!", "http://p2p.wrox.com");
//}
//});
</script>
</body>
</html>
EventUtil——跨浏览器的事件对象(https://www.cnblogs.com/hykun/p/EventUtil.html)
<div id="myBtn1">121212</div>
<script>
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) { //DOM2级
element.addEventListener(type, handler, false);
} else if (element.attachEvent) { //DOM1级
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler; //DOM0级
}
},
removeHandler: function (element, type, handler) { //类似addHandler
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
}
}
var btn1 = document.getElementById("myBtn1");
var handler = function () {
alert("hello handler");
}
EventUtil.addHandler(btn1, "click", handler);
</script>
16.2 拖放事件
draggable属性:是否可以拖动(true,false)
注:在 IE9 及更早版本中,通过 mousedown 事件处理程序调用 dragDrop()能够让 任何元素可拖动。而在 Safari 4 及之前版本中,必须额外给相应元素设置 CSS 样式 –khtml-user-drag: element。
拖动某元素时,将依次触发 下列事件:
1.ondragstart():按下鼠标键并开始移动鼠标时,会在被拖放的元素上触发 dragstart 事件;
2.ondragend():随即会触发 drag 事件,而且在元素被拖动期间会持续触发该事件,当拖动停止时(无 论是把元素放到了有效的放置目标,还是放到了无效的放置目标上),会触发 dragend 事件;
3.ondragend():拖动放开触发该事件
当某个元素被拖动到一个有效的放置目标上时,下列事件会依次发生:
1.ondragenter():当被鼠标拖动的对象进入其容器范围内时触发此事件;
2.ondragover():当某被拖动的对象在另一对象容器范围内拖动时触发此事件;
3.ondragleave():当被鼠标拖动的对象离开其容器范围内时触发此事件;
4.ondrop():在一个拖动过程中,释放鼠标键时触发此事件;
dataTransfer对象:dataTransfer 对象有两个主要方法:getData()和 setData()。不难想象,getData()可以取 得由 setData()保存的值。setData()方法的第一个参数,也是 getData()方法唯一的一个参数,是 一个字符串,表示保存的数据类型,取值为"text"或"URL"
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<style>
.droptarget {
float: left;
width: 100px;
height: 35px;
margin: 15px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
</head>
<body>
<p>在两个矩形框中来回拖动 p 元素:</p>
<div class="droptarget" ondrop="drop(event)" ondragover="allowDrop(event)">
<p ondragstart="dragStart(event)" ondragend="dragEnd(event)" draggable="true" id="dragtarget">拖动我!</p>
</div>
<div class="droptarget" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<p style="clear:both;"><strong>注意:</strong>Internet Explorer 8 及更早 IE 版本或 Safari 5.1 及更早版本的浏览器不支持 drag 事件。</p>
<p id="demo"></p>
<script>
function dragStart(event) {
event.dataTransfer.setData("Text", event.target.id);
document.getElementById("demo").innerHTML = "开始拖动 p 元素";
}
function dragEnd(event) {
document.getElementById("demo").innerHTML = "完成 p 元素的拖动。";
}
function allowDrop(event) {
event.preventDefault();
}
function drop(event) {
//消除默认事件
event.preventDefault();
//读取 URL var url = dataTransfer.getData("url") ||dataTransfer.getData("text/uri-list");
var data = event.dataTransfer.getData("Text");
event.target.appendChild(document.getElementById(data));
}
</script>
</body>
</html>
16.3 媒体元素
video:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<style>
.droptarget {
float: left;
width: 100px;
height: 35px;
margin: 15px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
</head>
<body>
<div class="mediaplayer">
<div class="video">
<video id="player" src="http://www.runoob.com/try/demo_source/movie.ogg" poster="http://tpc.googlesyndication.com/daca_images/simgad/7493640574537910849"
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>
<script>
//取得元素的引用
var player = document.getElementById("player"),
btn = document.getElementById("video-btn"),
curtime = document.getElementById("curtime"),
duration = document.getElementById("duration");
//更新播放时间
duration.innerHTML = player.duration;
//为按钮添加事件处理程序
btn.addEventListener("click", function(event){
if (player.paused){
player.play();
btn.value = "Pause";
} else {
player.pause();
btn.value = "Play";
}
});
//定时更新当前时间
setInterval(function(){
curtime.innerHTML = player.currentTime;
}, 250);
</script>
</body>
</html>
检测编解码器的支持情况:
var audio = document.getElementById("audio-player");
//很可能"maybe"
if (audio.canPlayType("audio/mpeg")){
//进一步处理 }
Audio类型:
//创建新的 Audio 实例即可开始下载指定的文件。下载完成后,调用 play()就可以播放音频。
//在 iOS 中,调用 play()时会弹出一个对话框,得到用户的许可后才能播放声音。如果想在一段音 频播放后再播放另一段音频,必须在 onfinish 事件处理程序中调用 play()方法
var audio = new Audio("sound.mp3"); EventUtil.addHandler(audio, "canplaythrough", function(event){
audio.play();
});
16.4 历史状态管理
history.pushState():通过 hashchange 事件,可以知道 URL 的参数什么时候发生了变化,即什么时候该有所反应。而 通过状态管理 API,能够在不加载新页面的情况下改变浏览器的 URL
//执行 pushState()方法后,新的状态信息就会被加入历史状态栈,而浏览器地址栏也会变成新的 相对 URL。但是,浏览器并不会真的向服务器发送请求,即使状态改变之后查询 location.href 也会 返回与地址栏中相同的地址。另外,第二个参数目前还没有浏览器实现,因此完全可以只传入一个空字 符串,或者一个短标题也可以。而第一个参数则应该尽可能提供初始化页面状态所需的各种信息。
history.pushState({name:"Nicholas"}, "Nicholas' page", "nicholas.html");
//要更新当前状态,可以调用 replaceState(),传入的参数与 pushState()的前两个参数相同。 调用这个方法不会在历史状态栈中创建新状态,只会重写当前状态
history.replaceState({name:"Greg"}, "Greg's page");