近日工作开发618活动,活动中有H5摇一摇功能以及声音和动画,百度瞄了几眼感觉封装的不太好,就试着自己去封装一套出来,下面记录一下这次开发做踩的坑: 1、H5摇一摇功能: 首先判断了一下,,设备是否支持摇一摇功能:``` if (window.DeviceMotionEvent) { 这里是具体的操作 } else { alert('你的浏览器不支持摇一摇功能.'); }
然后就封装方法,去监听'devicemotion'函数,``` window.addEventListener('devicemotion', handler, !1);
监听devicemotion函数是否触发,handler函数,是去做具体的操作当摇一摇功能触发;
function handler(e) { var current = e.accelerationIncludingGravity; var currentTime; var timeDifference; var deltaX = 0; var deltaY = 0; var deltaZ = 0; //记录上一次设备在x,y,z方向上的加速度 if ((lastX === null) && (lastY === null) && (lastZ === null)) { lastX = current.x; lastY = current.y; lastZ = current.z; return; } //得到两次移动各个方向上的加速度绝对差距 deltaX = Math.abs(lastX - current.x); deltaY = Math.abs(lastY - current.y); deltaZ = Math.abs(lastZ - current.z); //当差距大于设定的阀值并且时间间隔大于指定阀值时,触发摇一摇逻辑 if (((deltaX > threshold) && (deltaY > threshold)) || ((deltaX > threshold) && (deltaZ > threshold)) || ((deltaY > threshold) && (deltaZ > threshold))) { currentTime = new Date; timeDifference = currentTime.getTime() - lastTime.getTime(); //时间间隔 if (timeDifference > timeout && drawStatus) { //触发摇一摇事件 dealShake(); lastTime = new Date; } } lastX = current.x; lastY = current.y; lastZ = current.z; } function dealShake() { if (isShaking) return; // 判断状态是否为进行时,否则不触发 isShaking = !0; // 初始化状态 drawFun(); setTimeout(function () { $("#shakemusic")[0].pause(); isShaking = !1; }, 1500); }
进行到这一步发现,每一次去摇一摇手机都会触发好多次事件,这与本次功能不符,因为公司要求摇一次只能触发一次后台请求,然后我首先想到的是定时器,轮循,发现不行,每一次去摇动手机还是会触发多次,中间各种方法尝试,都没有解决,中间瞄了大神写的,找到了思路,就是当事件触发的时候记录一次时间,然后中间判断时间间隔是否满足初始时设置的时间间隔,以这种方式就完美解决了摇动一次触发多次事件的问题 2:H5 audio元素的撕逼之路: 吐槽一下IOS对于H5 audio和video元素的限制,这两个新属性在IOS上面是没有办法自动播放,只能用户去手动触发一次才可以播放,这就为一些H5页面带来了问题;不能立即播放; 因为是摇一摇的功能,所以用户进入摇奖页面是和手机没有相互交互的动作,所以就没有办法触发play事件,当然安卓手机上面是可以自动播放,所以也就不存在这个问题了;为了保持统一,只能在进入页面的时候手动在安卓手机的情况下把自动播放功能暂停;我选择的是在用户进入到摇一摇抽奖页面的时候,这个有一个交互,在这个动作的时候触发播放状态``` $('.flowBtn').one('touchstart', function(e) { $('#shakemusic').get(0).touchstart = true; $('#shakemusic').get(0).play(); $('#shakemusic').get(0).load(); return false; });