在 iOS 12. 1 以上版本,已经无法正常在浏览器或者 webview 中正常使用这两个事件,以前可以直接对 deviceorientation
进行监听,然后愉快地去获取设备的倾斜值,从而应用到实际的项目中,比如可以利用扩展设计器编写移动端扩展,从而可以在慧编程移动端上编写适合的小游戏,类似于重力感应可以实现很多有趣的东西。
而在 12.1 版本,官方默认将 Motion & Orientation settings
设置为禁用状态,可以打开 iPad 或者 iPhone 12.1 + 设备进入 settings - Safari - PRIVACY & SECURITY
中查看 Motion & Orientation Access
是否设置为可用,而在 13 版本中,官方已经将该入口隐藏,反正就是找不到了,一顿爆改。
但其实不用担心,iOS 12.1 + 版本提供 DeviceMotionEvent.requestPermission()|DeviceOrientationEvent.requestPermission()
用于获取动作和方向权限,这样一调用会弹出系统框,用于获取该权限,当用户点了允许后,采取监听 deviceorientation|devicemotion
方法,这样问题就解决了,也可以引导用户去点击上图的设置,设置为可用状态即可,但是只针对 13 以下的版本,13 版本已经找不到该入口。
实际的处理代码,可以参考下面示例。
const getDeviceOrientationEventPermission = function () {
if (DeviceOrientationEvent
&& DeviceOrientationEvent.requestPermission
&& typeof DeviceOrientationEvent.requestPermission === 'function'
) {
DeviceMotionEvent.requestPermission().then(permissionState => {
if(permissionState === "granted") {
window.addEventListener("devicemotion", function (e) {}, false);
} else if(permissionState === "denied") {
console.warn("用户拒绝授权。");
}
});
}
if (DeviceOrientationEvent
&& DeviceOrientationEvent.requestPermission
&& typeof DeviceOrientationEvent.requestPermission === 'function'
) {
DeviceOrientationEvent.requestPermission().then(permissionState => {
if(permissionState === "granted") {
window.addEventListener("deviceorientation", function (e) {}, false);
} else if(permissionState === "denied") {
console.warn("用户拒绝授权。");
}
});
}
}
而且需要注意的是,需要的进行授权的网站必须要有合格的 https 证书,否则在触发的时候,会抛出 Call to requestPermission() failed, reason: Browsing context is not secure.
错误,可以直接调试 iPad 端 Safari 打开的网站,直接输入 DeviceOrientationEvent.requestPermission()
即可知道是否允许授权,但实际应用中还是需要用户主动去触发获取权限,否则会抛出 Unhandled Promise Rejection: NotAllowedError: Requesting device orientation or motion access requires a user gesture to prompt
错误,可以直接打开 [baidu.com](http://baidu.com)
模拟一下,例如 document.getElementById('s_logo').onclick = getDeviceOrientationEventPermission
,这样只要点击以外的区域就可以正常弹出授权框。如果用户点了取消授权,会发现无论如何触发,授权窗口将不会再次唤起,只会输出 用户拒绝授权。
这一点跟 chrome 浏览器差不多,只能弹一次,后续只能用户自己去设置里进行授权。
由于 iOS 12.1 + 版本对动作和方向事件的使用变得很严格,所以想在 webview 中正常使用该功能,其实就变得很麻烦,首先你通过 getDeviceOrientationEventPermission
想去打开授权窗口,肯定是打不开的,所以如果想在 webview 中使用类似于动作或者方向的事件,不仅要 web 端去获取权限,而且原生端也要提供对应的支持,iOS 13 版本已经添加了 DeviceMotionEvent and DeviceOrientation 接口。
综上所述,如果用户想在扩展设计器编写移动端扩展,想用到动作和方向事件,实际上是没法做到全设备支持的,所以需要做好实际区分,用户在使用扩展的时候,若用户实际版本是 12.1 + ,需要告知用户无法正常使用该功能。
参考链接
iOS13 にて javascript の devicemotion を取得する
Get device motion and orientation back on iOS 13