年前在一个程序中需要用到摇一摇这个功能,忽然发现 devicemotion 这个事件在 IOS 下不起效果,查了一堆资料终于解决了这个问题。DeviceMotion 是什么?摇一摇这个功能具体怎么实现,在各个设备下需要处理什么样的问题,我们通过一篇文章来好好掰扯掰扯这个事情。
DeviceMotion 到底是何物?
在 window 对象中存在一个专门的事件 devicemotion,这个事件可以用来监听设备的加速度变化等信息.
在该事件的 Event 对象中(DeviceMotionEvent),包含了 acceleration 对象,我们可以同过 acceleration 对象来获取设备的加速度信息。演示代码如下:
<script>
window.addEventListener("devicemotion",(e)=>{
let motion = e.acceleration;
let {x,y,z} = motion;
// x,y,z 分别是手机三个方向的加速度
});
</script>
acceleration 对象中 x、y、z 分别代表了手机长、宽、厚,3个方向的加速度,具体如下图:
在这里我们已经了解 acceleration 的具体使用,接下来我们是不是就可以上手应用呢?先别急,接下来才是我们的踩坑之旅。接着往下我们来细聊一下,想要在手机上使用 acceleration 还有哪些坑在等着我们。
DeviceMotion 踩坑之旅
先从最简单的开始说起,在 安卓 下,使用 acceleration 时,在 X,Y,Z 三个方向取值时,要注意和IOS下刚好相反。
什么意思呢?比如 现在我使用的是一部安卓手机,向左移动,x轴得到一个速度为 10,那么相应 IOS 下 我们拿到的就是一个 -10,其他的Y轴和Z轴同理,处理一下兼容,得出下列代码:
<script>
// 判断是否是 IOS 设备,true 代表 IOS,false 代表非 IOS
function getIos(){
let u = window.navigator.userAgent;
return !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
}
window.addEventListener("devicemotion",(e)=>{
let motion = e.acceleration;
let {x,y,z} = motion;
if(!getIos()){
x = -x;
y = -y;
z = -z;
}
});
</script>
爬过了第一个坑之后,我们继续探坑,上述代码使用 IOS 的小伙伴可能一直看不到效果,这是为什么呢,一个版本一个版本的来说。
IOS 下的 https 要求
在 IOS 一开始的版本中是可以和安卓一样直接运行的,但是从 IOS 10 之后的某个版本(实在记不起来大家原谅), IOS 做了安全限制,要使用 devicemotion 事件则必须使用 https 协议。好吧,那既然官方要求了,咱也没有办法是吧,配吧。
终于在 IOS 协议配置好之后,问题应该能解决吧,少年你把这个问题想得太简单了。
IOS 12.2 之后的安全限制
在 IOS 12.2 之后,苹果的开发团队又给我们添了一个大乐子,用户可以在手机的设置关闭掉“动作与方向访问”,如下图所示。如果用户关闭了,那么我们就只能“呵呵”了,顺便说一下,目前为止,开发人员有没有有效的办法直接获取到用户是否关闭了“动作与方向访问”。