devicemotion事件监听器未执行函数问题求助
搞定DeviceMotionEvent监听器不触发的问题
嘿,我看了你遇到的问题——明明能检测到window.DeviceMotionEvent存在,但监听器里的代码就是不跑,这事儿我之前也碰到过,大概率是浏览器的安全限制在搞鬼,现在主流浏览器对传感器事件管得特别严,我给你拆解几个核心原因和解决办法:
1. 先确认你的站点是HTTPS(本地localhost除外)
现代浏览器(Chrome、Safari、Firefox这些)要求设备运动/方向事件必须在安全上下文里运行,也就是HTTPS协议,只有本地开发用的localhost能破例。如果你的部署环境是HTTP,哪怕你能检测到事件对象,浏览器也会直接把事件触发给拦了。
2. 必须等用户主动交互后再注册监听器(重点!)
从iOS 13开始,Safari就要求必须通过用户的主动操作(比如点击按钮)来请求传感器权限;Chrome在后续版本也跟进了这个规则——你不能在页面加载完就直接绑监听器,得等用户点个按钮啥的,再去注册事件监听。
我给你改了下代码,把事件监听的注册放到了input点击事件里:
var x, y, z, alpha, gamma, beta; var interval; var arr = {'data':[]}; var ON = false; // 标记监听器是否已经添加,避免重复绑定 var hasMotionListener = false; var hasOrientationListener = false; // 先确认事件对象存在 if (window.DeviceMotionEvent) { console.log("devicemotion was defined"); }; if (window.DeviceOrientationEvent) { console.log("GyroScope was defined"); }; $('input').on('click', function(){ ON = !ON; // 只有开启状态且没绑过监听器时,才注册事件 if(ON && !hasMotionListener){ // 绑定devicemotion window.addEventListener("devicemotion", function(event){ x = event.accelerationIncludingGravity.x; y = event.accelerationIncludingGravity.y; z = event.accelerationIncludingGravity.z; console.log(event); }, true); hasMotionListener = true; // 绑定deviceorientation window.addEventListener('deviceorientation', function(event){ alpha = event.alpha; gamma = event.gamma; beta = event.beta; }, true); hasOrientationListener = true; } // 记得在这里调用mainFunc,不然数据收集逻辑不会跑 mainFunc(); }); // 数据收集主函数 function mainFunc(){ if(ON){ interval = setInterval(() => { // 用push比concat更高效 arr['data'].push([x,y,z,alpha,gamma,beta]); if(arr['data'].length >=30){ send(); console.log(arr); } console.log([x,y,z,alpha,gamma,beta]); }, 200); } else { clearInterval(interval); } } // Ajax发送数据(建议把async改成true,同步请求会卡页面) function send(){ const savedData = arr['data']; arr['data'] = []; $.ajax({ url: "{% url 'detect' %}", data: arr, async: true, success: function(data){ if (data){ $('#indicator').fadeIn('slow').fadeOut('slow'); } } }); };
3. 检查浏览器的传感器权限设置
有些浏览器可能在设置里禁用了传感器访问:
- Chrome里可以输
chrome://settings/content/sensors,看看当前站点有没有权限 - Safari去偏好设置的“隐私”选项卡,找“网站使用传感器”的权限
4. 用真实移动设备测试
桌面浏览器的模拟器有时候传感器事件会有异常,建议拿真实的手机/平板测试,确保硬件本身支持传感器。
另外提一句,你原来的mainFunc()没被调用过,我在input点击事件里加了调用,不然数据收集的逻辑也不会启动哦。
内容的提问来源于stack exchange,提问作者eitroo
相关产品推荐
相关产品推荐

