横竖屏检测
window.orientation 检测手机横竖屏
- 90 -90 横屏
- 0 180 竖屏
setOrientation();
window.addEventListener("orientationchange",setOrientation);
function setOrientation(){
let box = document.querySelector("#box");
switch(window.orientation){
case 90:
case -90:
box.style.display = "flex";
break;
case 0:
case 180:
box.style.display = "none";
break;
}
}
加速度检测
监听手机加速度发生变化
- acceleration 手机加速度检测
- accelerationIncludingGravity 手机重力加速度检测(加速度 + 重力-地心引力)
{
let box = document.querySelector("#box");
// 监听手机加速度发生变化
window.addEventListener("devicemotion",(e)=>{
let motion = e.acceleration;//手机加速度信息
box.innerHTML = `
x:${motion.x.toFixed(0)}<br />
y:${motion.y.toFixed(0)}<br />
z:${motion.z.toFixed(0)}
`;
});
}
重力加速度
{
let box = document.querySelector("#box");
// 监听手机加速度发生变化
window.addEventListener("devicemotion",(e)=>{
let motion = e.accelerationIncludingGravity;//手机重力加速度信息(加速度 + 重力)
box.innerHTML = `
x:${motion.x.toFixed(0)}<br />
y:${motion.y.toFixed(0)}<br />
z:${motion.z.toFixed(0)}
`;
});
}
平衡球
{
let box = document.querySelector("#box");
let tx = 0;
let ty = 0;
// 监听手机加速度发生变化
window.addEventListener("devicemotion",(e)=>{
let motion = e.accelerationIncludingGravity;
let acceleration = e.acceleration;
let x = parseInt(motion.x) - parseInt(acceleration.x);
let y = parseInt(motion.y) - parseInt(acceleration.y);
tx += x;
ty -= y;
box.style.transform = `translate(${tx}px,${ty}px)`;
});
}
陀螺仪检测
摇一摇实现
document.querySelector("#btn").addEventListener("touchstart",function(){
shake(function(){
alert("摇一摇")
});
});
function throttle(fn,interval=200,isStart = true){
var timer = 0;
return function(...arg){
if(timer){
return ;
}
isStart&&fn.apply(this,arg);
timer = setTimeout(()=>{
timer = 0;
isStart||fn.apply(this,arg);
},interval);
}
}
// cb 当用户执行了摇一摇之后要做的事情
function shake(cb){
/*
摇一摇 一定时间内,加速度有一个比较大的变化
*/
var RANGE = 60; //当加速度差值大于该幅度时认定用户进行了摇一摇
var lastX = 0; // 上一次的加速度值
var lastY = 0;
var lastZ = 0;
var MINRANGE = 10;//当摇晃幅度低于该幅度时,我们认定摇一摇已经停止了
var isShake = false;
permissionMotion(throttle(function(e){
var motion = e.acceleration;
var x = motion.x;
var y = motion.y;
var z = motion.z;
var nowRange = Math.abs(x - lastX) + Math.abs(y - lastY) + Math.abs(z - lastZ);// 当前和上一次手机的摇晃幅度
if(nowRange > RANGE){
// 当当前摇晃幅度 大于我们设定的界限时认定用户进行了摇一摇
isShake = true;
} else if(nowRange < MINRANGE && isShake){
cb();
isShake = false;
}
lastX = x;
lastY = y;
lastZ = z;
}));
}
防抖函数
防抖:在用户频繁触发的时候,我们只识别一次(识别第一次/识别最后一次)
最初级:防止频繁点击触发
function func() {
console.log('OK');
}
// 防止频繁点击触发:设置标识进行判断
let isClick = false;
document.body.onclick = function () {
if (isClick) return;
isClick = true;
setTimeout(() => {
console.log('OK');
isClick = false;
}, 1000);
};
存在问题:只能控制执行间隔
升级版:保证上一个逻辑处理完成后再执行下一次
- 第一次点击,没有立即执行,等待500MS,看看这个时间内有没有触发第二次,
- 有触发第二次说明在频繁点击,不去执行我们的事情(继续看第三次和第二次间隔…)
- 如果没有触发第二次,则认为非频繁点击,此时再去触发;
- 科里化函数思想
- 或者只执行第一次,接下来都不执行,通过immediate 参数来控制
function debounce(func, wait = 500, immediate = false) {
let timer = null;
return function anonymous(...params) {
let now = immediate && !timer; // timer设置了定时器,说明就不是第一次执行了
clearTimeout(timer); // wait 时间内,如果再次触发就清除上一次的定时器
timer = setTimeout(() => {
timer = null;
// 执行函数:注意保持THIS和参数的完整度
!immediate ? func.call(this, ...params) : null;
}, wait);
// 只执行第一次
now ? func.call(this, ...params) : null;
};
}
function func() {
console.log("点击了");
}
document.body.onclick = debounce(func, 1000, true);
- debounce:实现函数的防抖(目的是频繁触发中只执行一次)
- @params
- func:需要执行的函数
- wait:检测防抖的间隔频率
- immediate:是否是立即执行(如果为TRUE是控制第一次触发的时候就执行函数,默认FALSE是以最后一次触发为准)
- @return
- 可被调用执行的函数
节流
- 比如浏览器滚动事件,浏览器检测到滚动就会触发很多次绑定的事件,也就是说函数的执行频率很高
- 而节流就是为了缩减这个频率而诞生的
- 和防抖的区别就在于节流是缩减频率而不是限定为只执行一次
实现
- throttle:实现函数的节流(目的是频繁触发中缩减频率)
- @params
- func:需要执行的函数
- wait:自己设定的间隔时间(频率)
- @return
- 可被调用执行的函数
- remaining 上次执行后剩下的间隔时间
function throttle(func, wait = 500) {
let timer = null,
previous = 0; //记录上一次操作时间
return function anonymous(...params) {
let now = new Date(), //当前操作的时间
remaining = wait - (now - previous);
if (remaining <= 0) {
// 两次间隔时间超过频率:把方法执行即可
clearTimeout(timer);
timer = null;
previous = now;
func.call(this, ...params);
}
if (remaining > 0 && !timer) { // 如果有定时器就不需要再定时,先把上一次的执行完成再说
// 两次间隔时间没有超过频率,说明还没有达到触发标准,设置定时器等待即可(还差多久等多久)
timer = setTimeout(() => {
clearTimeout(timer);
timer = null;
previous = new Date();
func.call(this, ...params);
}, remaining);
}
};
}
function func() {
console.log("滚动了");
}
document.body.onscroll = throttle(func, 500);