横竖屏检测

window.orientation 检测手机横竖屏

  • 90 -90 横屏
  • 0 180 竖屏
  1. setOrientation();
  2. window.addEventListener("orientationchange",setOrientation);
  3. function setOrientation(){
  4. let box = document.querySelector("#box");
  5. switch(window.orientation){
  6. case 90:
  7. case -90:
  8. box.style.display = "flex";
  9. break;
  10. case 0:
  11. case 180:
  12. box.style.display = "none";
  13. break;
  14. }
  15. }

加速度检测

监听手机加速度发生变化

  • acceleration 手机加速度检测
  • accelerationIncludingGravity 手机重力加速度检测(加速度 + 重力-地心引力)
    1. {
    2. let box = document.querySelector("#box");
    3. // 监听手机加速度发生变化
    4. window.addEventListener("devicemotion",(e)=>{
    5. let motion = e.acceleration;//手机加速度信息
    6. box.innerHTML = `
    7. x:${motion.x.toFixed(0)}<br />
    8. y:${motion.y.toFixed(0)}<br />
    9. z:${motion.z.toFixed(0)}
    10. `;
    11. });
    12. }

XYZ.jpg

重力加速度

  1. {
  2. let box = document.querySelector("#box");
  3. // 监听手机加速度发生变化
  4. window.addEventListener("devicemotion",(e)=>{
  5. let motion = e.accelerationIncludingGravity;//手机重力加速度信息(加速度 + 重力)
  6. box.innerHTML = `
  7. x:${motion.x.toFixed(0)}<br />
  8. y:${motion.y.toFixed(0)}<br />
  9. z:${motion.z.toFixed(0)}
  10. `;
  11. });
  12. }

平衡球

  1. {
  2. let box = document.querySelector("#box");
  3. let tx = 0;
  4. let ty = 0;
  5. // 监听手机加速度发生变化
  6. window.addEventListener("devicemotion",(e)=>{
  7. let motion = e.accelerationIncludingGravity;
  8. let acceleration = e.acceleration;
  9. let x = parseInt(motion.x) - parseInt(acceleration.x);
  10. let y = parseInt(motion.y) - parseInt(acceleration.y);
  11. tx += x;
  12. ty -= y;
  13. box.style.transform = `translate(${tx}px,${ty}px)`;
  14. });
  15. }

陀螺仪检测

摇一摇实现

  1. document.querySelector("#btn").addEventListener("touchstart",function(){
  2. shake(function(){
  3. alert("摇一摇")
  4. });
  5. });
  6. function throttle(fn,interval=200,isStart = true){
  7. var timer = 0;
  8. return function(...arg){
  9. if(timer){
  10. return ;
  11. }
  12. isStart&&fn.apply(this,arg);
  13. timer = setTimeout(()=>{
  14. timer = 0;
  15. isStart||fn.apply(this,arg);
  16. },interval);
  17. }
  18. }
  19. // cb 当用户执行了摇一摇之后要做的事情
  20. function shake(cb){
  21. /*
  22. 摇一摇 一定时间内,加速度有一个比较大的变化
  23. */
  24. var RANGE = 60; //当加速度差值大于该幅度时认定用户进行了摇一摇
  25. var lastX = 0; // 上一次的加速度值
  26. var lastY = 0;
  27. var lastZ = 0;
  28. var MINRANGE = 10;//当摇晃幅度低于该幅度时,我们认定摇一摇已经停止了
  29. var isShake = false;
  30. permissionMotion(throttle(function(e){
  31. var motion = e.acceleration;
  32. var x = motion.x;
  33. var y = motion.y;
  34. var z = motion.z;
  35. var nowRange = Math.abs(x - lastX) + Math.abs(y - lastY) + Math.abs(z - lastZ);// 当前和上一次手机的摇晃幅度
  36. if(nowRange > RANGE){
  37. // 当当前摇晃幅度 大于我们设定的界限时认定用户进行了摇一摇
  38. isShake = true;
  39. } else if(nowRange < MINRANGE && isShake){
  40. cb();
  41. isShake = false;
  42. }
  43. lastX = x;
  44. lastY = y;
  45. lastZ = z;
  46. }));
  47. }

防抖函数

防抖:在用户频繁触发的时候,我们只识别一次(识别第一次/识别最后一次)

最初级:防止频繁点击触发

  1. function func() {
  2. console.log('OK');
  3. }
  4. // 防止频繁点击触发:设置标识进行判断
  5. let isClick = false;
  6. document.body.onclick = function () {
  7. if (isClick) return;
  8. isClick = true;
  9. setTimeout(() => {
  10. console.log('OK');
  11. isClick = false;
  12. }, 1000);
  13. };

存在问题:只能控制执行间隔

升级版:保证上一个逻辑处理完成后再执行下一次

  1. 第一次点击,没有立即执行,等待500MS,看看这个时间内有没有触发第二次,
  2. 有触发第二次说明在频繁点击,不去执行我们的事情(继续看第三次和第二次间隔…)
  3. 如果没有触发第二次,则认为非频繁点击,此时再去触发;
  4. 科里化函数思想
  5. 或者只执行第一次,接下来都不执行,通过immediate 参数来控制
  1. function debounce(func, wait = 500, immediate = false) {
  2. let timer = null;
  3. return function anonymous(...params) {
  4. let now = immediate && !timer; // timer设置了定时器,说明就不是第一次执行了
  5. clearTimeout(timer); // wait 时间内,如果再次触发就清除上一次的定时器
  6. timer = setTimeout(() => {
  7. timer = null;
  8. // 执行函数:注意保持THIS和参数的完整度
  9. !immediate ? func.call(this, ...params) : null;
  10. }, wait);
  11. // 只执行第一次
  12. now ? func.call(this, ...params) : null;
  13. };
  14. }
  15. function func() {
  16. console.log("点击了");
  17. }
  18. document.body.onclick = debounce(func, 1000, true);
  • debounce:实现函数的防抖(目的是频繁触发中只执行一次)
  • @params
    • func:需要执行的函数
    • wait:检测防抖的间隔频率
    • immediate:是否是立即执行(如果为TRUE是控制第一次触发的时候就执行函数,默认FALSE是以最后一次触发为准
  • @return
    • 可被调用执行的函数

节流

  • 比如浏览器滚动事件,浏览器检测到滚动就会触发很多次绑定的事件,也就是说函数的执行频率很高
  • 而节流就是为了缩减这个频率而诞生的
  • 和防抖的区别就在于节流是缩减频率而不是限定为只执行一次

实现

  • throttle:实现函数的节流(目的是频繁触发中缩减频率)
  • @params
    • func:需要执行的函数
    • wait:自己设定的间隔时间(频率)
  • @return
    • 可被调用执行的函数
  • remaining 上次执行后剩下的间隔时间
  1. function throttle(func, wait = 500) {
  2. let timer = null,
  3. previous = 0; //记录上一次操作时间
  4. return function anonymous(...params) {
  5. let now = new Date(), //当前操作的时间
  6. remaining = wait - (now - previous);
  7. if (remaining <= 0) {
  8. // 两次间隔时间超过频率:把方法执行即可
  9. clearTimeout(timer);
  10. timer = null;
  11. previous = now;
  12. func.call(this, ...params);
  13. }
  14. if (remaining > 0 && !timer) { // 如果有定时器就不需要再定时,先把上一次的执行完成再说
  15. // 两次间隔时间没有超过频率,说明还没有达到触发标准,设置定时器等待即可(还差多久等多久)
  16. timer = setTimeout(() => {
  17. clearTimeout(timer);
  18. timer = null;
  19. previous = new Date();
  20. func.call(this, ...params);
  21. }, remaining);
  22. }
  23. };
  24. }
  25. function func() {
  26. console.log("滚动了");
  27. }
  28. document.body.onscroll = throttle(func, 500);