h5实现手机摇一摇功能
实现原理
手机摇一摇功能基于设备加速度传感器(DeviceMotionEvent),通过监听设备的加速度变化来判断用户是否进行了摇晃动作。HTML5提供了相关API获取设备传感器数据。

基本实现步骤
监听设备运动事件
在JavaScript中,通过devicemotion事件获取设备加速度数据。需要先检查浏览器是否支持该API:

if (window.DeviceMotionEvent) {
window.addEventListener('devicemotion', handleMotion);
} else {
alert("您的设备不支持摇一摇功能");
}
处理加速度数据 在事件处理函数中,计算三个轴向(x,y,z)的加速度变化量。当变化量超过设定阈值时触发摇动事件:
let lastTime = 0;
let threshold = 15; // 摇晃强度阈值
let shakeTimeout = null;
function handleMotion(event) {
const acceleration = event.accelerationIncludingGravity;
const currentTime = Date.now();
if ((currentTime - lastTime) > 100) { // 限制检测频率
const deltaX = Math.abs(acceleration.x);
const deltaY = Math.abs(acceleration.y);
const deltaZ = Math.abs(acceleration.z);
if ((deltaX > threshold) || (deltaY > threshold) || (deltaZ > threshold)) {
clearTimeout(shakeTimeout);
shakeTimeout = setTimeout(() => {
// 触发摇动后的操作
onShakeSuccess();
}, 200);
}
lastTime = currentTime;
}
}
权限请求(iOS13+) iOS13及以上版本需要先请求设备运动权限:
function requestPermission() {
if (typeof DeviceMotionEvent !== 'undefined' &&
typeof DeviceMotionEvent.requestPermission === 'function') {
DeviceMotionEvent.requestPermission()
.then(response => {
if (response === 'granted') {
window.addEventListener('devicemotion', handleMotion);
}
});
}
}
完整示例代码
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, user-scalable=no">
<title>摇一摇</title>
</head>
<body>
<h1>摇动手机触发事件</h1>
<script>
let lastTime = 0;
let threshold = 15;
let shakeTimeout = null;
function initShake() {
if (typeof DeviceMotionEvent !== 'undefined') {
if (typeof DeviceMotionEvent.requestPermission === 'function') {
// iOS13+需要权限请求
document.body.addEventListener('click', () => {
DeviceMotionEvent.requestPermission()
.then(permissionState => {
if (permissionState === 'granted') {
startShakeDetection();
}
});
});
} else {
// 其他设备直接开始
startShakeDetection();
}
} else {
alert("您的设备不支持摇一摇");
}
}
function startShakeDetection() {
window.addEventListener('devicemotion', handleMotion);
}
function handleMotion(event) {
const currentTime = Date.now();
if ((currentTime - lastTime) > 100) {
const acc = event.accelerationIncludingGravity;
const deltaX = Math.abs(acc.x);
const deltaY = Math.abs(acc.y);
const deltaZ = Math.abs(acc.z);
if (deltaX > threshold || deltaY > threshold || deltaZ > threshold) {
clearTimeout(shakeTimeout);
shakeTimeout = setTimeout(onShakeSuccess, 200);
}
lastTime = currentTime;
}
}
function onShakeSuccess() {
alert("摇动成功!");
// 这里可以执行其他操作,如跳转页面等
}
// 页面加载后初始化
window.onload = initShake;
</script>
</body>
</html>
注意事项
- 不同设备的传感器灵敏度差异较大,需要根据实际情况调整阈值(threshold)
- iOS系统需要用户交互(如点击事件)后才能请求传感器权限
- 部分安卓浏览器可能不支持加速度数据获取
- 在微信等内置浏览器中可能需要额外配置
- 建议添加防抖机制避免多次触发
优化建议
- 可以添加视觉反馈,当检测到摇动时改变页面元素样式
- 记录摇动次数或强度实现游戏化设计
- 结合GPS等传感器实现更复杂的位置相关功能






