前端开发之防抖与节流

前端开发中我们经常会通过监听某些事件来完成项目需求
1.通过监听 scroll 事件,检测滚动位置,根据滚动位置显示返回顶部按钮
2.通过监听 resize 事件,对某些自适应页面调整DOM的渲染(通过CSS实现的自适应不再此范围内)
3.通过监听 keyup 事件,监听文字输入并调用接口进行模糊匹配

scroll事件

window.onscroll  = function () {
    //滚动条位置
    let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
  console.log('滚动条位置:' + scrollTop);
}

在这里插入图片描述
从效果上,我们可以看到,在页面滚动的时候,会在短时间内触发多次绑定事件。

我们知道DOM操作是很耗费性能的,如果在监听中,做了一些DOM操作,那无疑会给浏览器造成大量性能损失。

下面我们进入主题,一起来探究,如何对此进行优化。

防抖:
通俗理解就是:延时处理,然后如果在这段延时内又触发了事件,则重新开始延时。
原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。

防抖实例:

let timer
window.onscroll=function(){
    if(timer){
        clearTimeout(timer)
    }
    timer=setTimeout(function(){
        //滚动位置
        let scrollTop=document.body.scrollTop|| document.documentElement.scrollTop;
        console.log('滚动条位置:' + scrollTop)
        timer=undefined
    },200)
}

实例效果:
在这里插入图片描述
函数封装:

/**
 * 防抖函数
 * @param method 事件触发的操作
 * @param delay 多少毫秒内连续触发事件,不会执行
 * @returns {Function}
 */
function debounce(method,delay) {
    let timer = null;
    return function () {
        let self = this,
            args = arguments;
        timer && clearTimeout(timer);
        timer = setTimeout(function () {
            method.apply(self,args);
        },delay);
    }
}
window.onscroll = debounce(function () {
    let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log('滚动条位置:' + scrollTop);
},200)

节流:
定义:触发函数事件后,短时间间隔内无法连续调用,只有上一次函数执行后,过了规定的时间间隔,才能进行下一次的函数调用。

原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。

let startTime =Date.now();//开始时间
let time =500;//间隔时间
let timer;
window.onscroll = function throttle(){
      let currentTime=Date.now();
      if(currentTime - startTime >= time){
        let scrollTop = document.body.scroll||document.documentElement.scrollTop;
        console.log('滚动条位置:' + scrollTop);
        startTime = currentTime;
      }else{
        clearTimeout(timer);
        timer=setTimeout(function(){
           throttle()
        },50)
      }
}

实例效果:每隔500毫秒触发一次事件
在这里插入图片描述
函数封装:

/**
 * 节流函数
 * @param method 事件触发的操作
 * @param mustRunDelay 间隔多少毫秒需要触发一次事件
 */
function throttle(method, mustRunDelay) {
    let timer,
        args = arguments,
        start;
    return function loop() {
        let self = this;
        let now = Date.now();
        if(!start){
            start = now;
        }
        if(timer){
            clearTimeout(timer);
        }
        if(now - start >= mustRunDelay){
            method.apply(self, args);
            start = now;
        }else {
            timer = setTimeout(function () {
                loop.apply(self, args);
            }, 50);
        }
    }
}
window.onscroll = throttle(function () {
    let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log('滚动条位置:' + scrollTop);
},800)

vue输入节流,避免实时请求接口
在做搜索的时候,当搜索页面只有一个输入框、没有确定按钮的时候,只能在用户输入时请求服务端,查询数据。这样会导致频繁的发送请求,造成服务端压力。解决这个问题,可以使用vue做输入节流。

1.创建一个工具类,debounce.js

/***
 * @param func 输入完成的回调函数
 * @param delay 延迟时间
 */
 export function debounce(func, delay){
   let timer
   return (...args)=>{
      if(timer){
         clearTimeout(timer)
      }
      timer=setTimeout(()=>{
         func.apply(this, args)
      },delay)
   }
 }

2、在搜索页面使用

<template>
    <div class="xn-container">
        <input type="text" class="text-input" v-model="search">
    </div>
</template>

<script>
    import {debounce} from '../utils/debounce'
    export default {
        name: 'HelloWorld',
        data () {
            return {
                search: ''
            }
        },
        created() {
            this.$watch('search', debounce((newQuery) => {
                // newQuery为输入的值
                console.log(newQuery)
            }, 200))
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
    .text-input {
        display: block;
        width: 100%;
        height: 44px;
        border: 1px solid #d5d8df;
    }
</style>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值