公司准备开年会了,年会活动用了一套别人的系统,根据测试,有些游戏的摇一摇功能在IOS上无法使用,为了修复该功能,踩了一些坑,特此记录如下:
1. 因为IOS系统的安全要求,项目必须是在https的域名下;
2. IOS系统13.3以后必须用户授权,才能使用重力与方向;
3. 用户授权时必须是手动触发完成,这点特别重要,比如点击一个按钮;
以下是代码实现,方便大家作参考:
<!DOCTYPE html>
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta http-equiv="content-security-policy">
<html>
<head>
<meta charset="utf-8" />
<title>IOS系统中H5页面实现摇一摇功能</title>
<style>
button {
width: 200px;
height: 60px;
font-size: 18px;
text-align: center;
position: fixed;
left:50%;
top:50%;
transform: translate(-50%,-50%);
}
</style>
</head>
<body>
<button>点击授权</button>
</body>
<script>
// 定义一个摇动阈值
var shakeThreshold = 500;
// 三个方向上次的值
var lastX, lastY, lastZ;
// 上一次摇动的时间
var lastTime = 0;
// 用户摇一摇的功能
function shakeFunction() {
var system = navigator.userAgent.toLowerCase();
if (system.indexOf("like mac os x") > 0) {
var reg = /os [\d._]*/gi;
var info = system.match(reg);
var version = (info + "").replace(/[^0-9|_.]/ig, "").replace(/_/ig, ".");
var list = version.split(".");
// 对IOS 13.3以后的版本处理
if (list[0] > 12 && list[1] > 2) {
if (typeof (DeviceMotionEvent) !== 'undefined' && typeof (DeviceMotionEvent.requestPermission) === 'function') {
window.DeviceOrientationEvent.requestPermission().then(state => {
if (state === "granted") {
// 监听传感器运动事件
if (window.DeviceMotionEvent) {
alert("授权成功")
window.addEventListener('devicemotion', shakeFunctionHandler);
} else {
alert('手机不支持陀螺仪功能');
}
} else if (state === "denied") {
alert("拒绝授权")
} else if (state === "prompt") {
alert("你对手机做了啥")
}
})
}
} else {
// 监听传感器运动事件
if (window.DeviceMotionEvent) {
window.addEventListener('devicemotion', shakeFunctionHandler);
} else {
alert('手机不支持陀螺仪功能');
}
}
}
};
// 运动传感器的处理
function shakeFunctionHandler(e) {
var currentTime = Date.now();
// 每100毫秒判断一次位置
if ((currentTime - lastTime) > 100) {
// 获取重力加速度
var acceleration = e.accelerationIncludingGravity;
var x = acceleration.x;
var y = acceleration.y;
var z = acceleration.z;
var differenceTime = currentTime - lastTime;
var speed = Math.abs(x + y + z - lastX - lastY - lastZ) / differenceTime * 10000;
// 前后三个向的差值的绝对值和时间比率超过了预设的阈值
if (speed > shakeThreshold) {
alert('手机开始摇起来了');
};
lastX = x;
lastY = y;
lastZ = z;
lastTime = currentTime;
}
}
</script>
</html>