HTML5定义了一些新的标记规则,也定义了一些新的JavaScript API,能够让开发人员创建出更好的用户界面。
- 跨文档消息API 能够在不降低同源策略安全性的前提下,在不同域间的文档间传递消息
- 原生拖放功能可以指定某个元素可拖动,并在操作系统要放置时做出响应,可以创建可拖动元素及放置目标
- 媒体元素
<audio>
和<video>
拥有自己与音频和视频交互的API,使用canPlayType()
检查浏览器是否支持特定格式 - 历史状态管理可以在不必卸载当前页面时修改浏览器的历史状态栈,在这种机制下,用户可以通过后退和前进按钮在页面状态间切换,这些状态完全由JavaScript控制
1. 跨文档消息传送
window.postMessage()
方法可以安全地实现跨源通信,通常对于两个不同页面的脚本,只有当执行他们的页面位于相同的协议 (通常为https
),端口号 (443 为https
),以及主机名,两个脚本之间能够相互通信。window.postMessage()
方法提供了一种受控机制来规避此限制,只要正确使用,这种方法就很安全。
otherWindow.postMessage(message, targetOrigin, [transfer])
otherWindow
其它窗口的一个引用,比如iframe
的contentWidow
属性,执行window.open
返回的窗口对象,或是命名过或数值索引的window.frames
message
将要发送到其它window
的数据,将会被结构化克隆算法序列化,可以不受限制地将数据对象安全地传送给窗口而无需自己序列化targetOrigin
通过窗口的origin
属性来指定哪些窗口能接收到消息事件,设置为*
时,能够把消息发送给来自任何域的文档一串和
message
同时传递的Transferable
对象,这些对象的所有权将被转移给消息的接收方
window.postMessage()
方法被调用时,会在所有页面脚本执行完毕后,向目标窗口派发一个messageEvent
消息,data
属性为window.postMessage
的第一个参数,origin
为调用postMessage
时消息发送方窗口的origin
,source
为对发送消息的窗口的引用
跨文档消息传送,简称为 XDM,指的是在不同域的页面间传递消息,使用postMessage()
方法,实现一个页面向包含在当前页面中的<iframe>
元素或者由当前页面弹出的窗口发送消息,方法的参数为一条消息和一个消息接收方的域名。
2. 原生拖放
拖动元素时,依次触发
dragstart
drag
dragend
当元素被拖动到一个有效的放置目标上时
dragenter
dragover
-
dragleave
或drop
dataTransfer
对象是事件对象的属性,用于从被拖动元素向放置目标传递字符串格式的数据,有getData()
和setData()
两个方法。IE中只定义了text
和URL
,HTML5中这两种类型被映射为text/plain
和text/uri-list
。保存在dataTransfer
对象中的数据只能在drop
事件处理程序中读取。dataTransfer
对象的dropEffect
属性可以知道被拖动的元素能够执行哪种放置行为
none
move
copy
link
dropEffect
属性只与effectAllowed
属性搭配才有用,必须在ondragstart
事件处理程序中设置effectAllowed
属性
uninitialized
none
copy
link
move
copyLink
copyMove
linkMove
all
对元素设置draggable
属性可以设置元素是否可拖动。dataTransfer
的其他方法和属性:
-
addElement(ele)
为拖动添加一个元素 -
clearData()
清除以特定格式保存的数据 -
setDragImage(ele, x, y)
指定一副图像,当拖动发生时,显示在光标下方 -
types
当前保存的数据类型
腾讯面试 页面内有一个正方形元素 A 和 一个待放置区域 B,对其实现拖拽和放下到 B 区域,并改变 B 区域背景颜色,不可用html5原生事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div#a {
width: 80px;
height: 80px;
background-color: green;
font-size: 20px;
color: white;
position: absolute;
z-index: 2;
}
div#b {
width: 200px;
height: 200px;
background-color: blueviolet;
font-size: 20px;
color: white;
position: absolute;
margin-top: 300px;
z-index: 1;
}
</style>
</head>
<body>
<div id='a'>A</div>
<div id='b'>B</div>
<script defer>
var aModel = document.getElementById('a')
var bModel = document.getElementById('b')
var positionAInitial = {
left: aModel.offsetLeft,
top: aModel.offsetTop
}
var positionB = {
xL: bModel.offsetLeft,
xR: bModel.offsetleft + bModel.clientWidth,
yL: bModel.offsetTop,
yR: bModel.offsetTop + bModel.clientHeight
}
var flag = false
var inB = false
aModel.addEventListener('mousedown', function() {
flag = true
})
aModel.addEventListener('mousemove', function(event) {
if (flag) {
var position = {
x: event.pageX,
y: event.pageY
}
aModel.style.left = position.x - positionAInitial.left + 'px'
aModel.style.top = position.y - positionAInitial.top + 'px'
aModel.opacity = '0.5'
inB = false
var positionA = {
left: aModel.offsetLeft,
right: aModel.offsetLeft + aModel.clientWidth,
top: aModel.offsetTop,
bottom: aModel.offsetTop + aModel.clientHeight,
}
if ((positionA.top <= positionB.yL && positionA.bottom >= positionB.yL) ||
(positionA.top <= positionB.yR && positionA.bottom >= positionB.yR) ||
(positionA.top >= positionB.yL && positionA.bottom <= positionB.yR)
) {
inB = true
}
}
})
aModel.addEventListener('mouseup', function(event) {
if (inB) {
aModel.style.opacity = '1'
bModel.style.backgroundColor = 'yellow'
} else {
aModel.style.left = positionAInitial.left + 'px'
aModel.style.top = positionAInitial.top + 'px'
aModel.style.opacity = '1'
}
flag = false
inB = false
})
</script>
</body>
3. 媒体元素
<audio>
和 <video>
能够在网页中嵌入跨浏览器的音频和视频内容,允许为媒体创建自定义的控件,并且提供了完善的属性和事件。canPlayType
检测浏览器是否支持某种编码解码器。
历史状态管理
通过 history
对象进行历史状态管理,可以在不卸载当前页面就能够修改浏览器的历史状态栈,用户能够通过前进和后退按钮在页面状态间切换,这些状态完全由 JavaScript 控制。属性和方法包括:
length
state
back()
forward()
go()
-
pushState()
将新的状态信息加入历史状态栈 -
replace()
更新当前状态