DeviceOrientationEvent 规范也定义了devicemotion 事件。这个事件用于提示设备实际上在移动,
而不仅仅是改变了朝向。例如,devicemotion 事件可以用来确定设备正在掉落或者正拿在一个行走的
人手里。
当devicemotion 事件触发时,event 对象中包含如下额外的属性。
acceleration:对象,包含x、y 和z 属性,反映不考虑重力情况下各个维度的加速信息。
accelerationIncludingGravity:对象,包含x、y 和z 属性,反映各个维度的加速信息,
包含z 轴自然重力加速度。
interval:毫秒,距离下次触发devicemotion 事件的时间。此值在事件之间应为常量。
rotationRate:对象,包含alpha、beta 和gamma 属性,表示设备朝向。
如果无法提供acceleration、accelerationIncludingGravity 和rotationRate 信息,则
属性值为null。为此,在使用这些属性前必须先检测它们的值是否为null。比如:
window.addEventListener(“devicemotion”, (event) => {
let output = document.getElementById(“output”);
if (event.rotationRate !== null) {
output.innerHTML += Alpha=${event.rotationRate.alpha}
+
Beta=${event.rotationRate.beta}
+
Gamma=${event.rotationRate.gamma}
;
}
});
触摸及手势事件
Safari 为iOS 定制了一些专有事件,以方便开发者。因为iOS 设备没有鼠标和键盘,所以常规的鼠
标和键盘事件不足以创建具有完整交互能力的
网页。同时,WebKit 也为Android 定制了很多专有事件,
成为了事实标准,并被纳入W3C 的Touch Events 规范。本节介绍的事件只适用于触屏设备。
- 触摸事件
iPhone 3G 发布时,iOS 2.0 内置了新版本的Safari。这个新的移动Safari 支持一些与触摸交互有关的
新事件。后来的Android 浏览器也实现了同样的事件。当手指放在屏幕上、在屏幕上滑动或从屏幕移开
时,触摸事件即会触发。触摸事件有如下几种。
touchstart:手指放到屏幕上时触发(即使有一个手指已经放在了屏幕上)。
touchmove:手指在屏幕上滑动时连续触发。在这个事件中调用preventDefault()可以阻止
滚动。
touchend:手指从屏幕上移开时触发。
touchcancel:系统停止跟踪触摸时触发。文档中并未明确什么情况下停止跟踪。
这些事件都会冒泡,也都可以被取消。尽管触摸事件不属于DOM 规范,但浏览器仍然以兼容DOM
的方式实现了它们。因此,每个触摸事件的event 对象都提供了鼠标事件的公共属性:bubbles、
cancelable、view、clientX、clientY、screenX、screenY、detail、altKey、shiftKey、
ctrlKey 和metaKey。
除了这些公共的DOM 属性,触摸事件还提供了以下3 个属性用于跟踪触点。
touches:Touch 对象的数组,表示当前屏幕上的每个触点。
targetTouches:Touch 对象的数组,表示特定于事件目标的触点。
changedTouches:Touch 对象的数组,表示自上次用户动作之后变化的触点。
每个Touch 对象都包含下列属性。
clientX:触点在视口中的x 坐标。
clientY:触点在视口中的y 坐标。
identifier:触点ID。
pageX:触点在页面上的x 坐标。
pageY:触点在页面上的y 坐标。
screenX:触点在屏幕上的x 坐标。
screenY:触点在屏幕上的y 坐标。
target:触摸事件的事件目标。
这些属性可用于追踪屏幕上的触摸轨迹。例如:
function handleTouchEvent(event) {
// 只针对一个触点
if (event.touches.length == 1) {
let output = document.getElementById(“output”);
switch(event.type) {
case “touchstart”:
output.innerHTML +=<br>Touch started:
+
(${event.touches[0].clientX}
+
${event.touches[0].clientY})
;
break;
case “touchend”:
output.innerHTML +=<br>Touch ended:
+
(${event.changedTouches[0].clientX}
+
${event.changedTouches[0].clientY})
;
break;
case “touchmove”:
event.preventDefault(); // 阻止滚动
output.innerHTML +=<br>Touch moved:
+
(${event.changedTouches[0].clientX}
+
${event.changedTouches[0].clientY})
;
break;
}
}
}
document.addEventListener(“touchstart”, handleTouchEvent);
document.addEventListener(“touchend”, handleTouchEvent);
document.addEventListener(“touchmove”, handleTouchEvent);
以上代码会追踪屏幕上的一个触点。为简单起见,代码只会在屏幕有一个触点时输出信息。在
touchstart 事件触发时,触点的位置信息会输出到output 元素中。在touchmove 事件触发时,会
取消默认行为以阻止滚动(移动触点通常会滚动页面),并输出变化的触点信息。在touchend 事件触
发时,会输出触点最后的信息。注意,touchend 事件触发时touches 集合中什么也没有,这是因为
没有滚动的触点了。此时必须使用changedTouches 集合。
这些事件会在文档的所有元素上触发,因此可以分别控制页面的不同部分。当手指点触屏幕上的元
素时,依次会发生如下事件(包括鼠标事件):
(1) touchstart
(2) mouseover
(3) mousemove(1 次)
(4) mousedown
(5) mouseup
(6) click
(7) touchend