kying-star的博客

vuePress-theme-reco kying-star的博客    2023
kying-star的博客

Choose mode

  • dark
  • auto
  • light
主页
指北
语言学习
AI
前端
后端
算法
杂项
github

kying-star的博客

7

Article

0

Tag

主页
指北
语言学习
AI
前端
后端
算法
杂项
github
  • js
    • 彻底了解This指针
    • 原型与原型链
    • AJAX
    • 防抖与节流
    • 闭包
    • 懒加载
    • 轮播图
    • js作用域
    • JS高阶函数和运行机制
  • css
  • vue
  • typescript
  • React
  • 前端新技术
  • 正则表达式
  • 浏览器

vuePress-theme-reco kying-star的博客    2023

防抖与节流

kying-star的博客

# 防抖与节流

# 防抖

事件响应函数在一段时间后才执行

如果在这段时间内在此调用,则重新计算执行时间。

当预定的时间内没有再次调用,则执行响应逻辑。

也就是说在事件触发结束后。在调用响应函数

举例

就相当于开车,当乘客都上完之后才会开车,这就是防抖

实现防抖 debounce()

第一版

function debounce(func,wait){
    let timeout;
    return function(){
        clearTimeout(timeout);
       timeout = setTimeout(func,wait);
    }
}//函数防抖
var container1 = document.querySelector('.container');
var count = 0;
function dosomething(){//触发函数
    console.log(this)//windows{}
    container1.innerHTML = count++;
}
container1.onmousemove = debounce(dosomething,300)

//问题dosomething()中this指向的是windows{}

解决方式如下

function debounce(func,wait){
    let timeout;
    console.log(`this${this}`);
    
    return function(){
       let context = this;
        clearTimeout(timeout);
       timeout = setTimeout(function(){
           func.apply(context);
       },wait);
    }
}
var container1 = document.querySelector('.container');
var count = 0;
function dosomething(event){
    console.log(event)//undefined
    console.log(this)
    container1.innerHTML = count++;
}
container1.onmousemove = debounce(dosomething,300)

通过apply改变func中的this的指向,让他指向触发事件的容器

但是还有问题没有解决,我们还不能获取事件对象

解决方法

function debounce(func,wait){
    let timeout;
    console.log(`this${this}`);
    
    return function(){
        let args = arguments
       let context = this;
        clearTimeout(timeout);
       timeout = setTimeout(function(){
           func.apply(context,args);
       },wait);
    }
}
var container1 = document.querySelector('.container');
var count = 0;
function dosomething(event){
    console.log(this)
    console.log(event)
    container1.innerHTML = count++;
}
container1.onmousemove = debounce(dosomething,300)

利用arguments获取事件对象,附加到apply中

进一步优化

function debounce(func, wait,immediate) {
    let timeout;
    return function () {
        let args = arguments
        let context = this;
        clearTimeout(timeout);
        if (immediate) {
            callnow = !timeout;
            timeout = setTimeout(()=>{
                timeout = null;
            },wait)
            if(callnow) func.apply(context,args)
        } else {
            timeout = setTimeout(function () {
                func.apply(context, args);
            }, wait);
        }

    }
}
var container1 = document.querySelector('.container');
var count = 0;
function dosomething(event) {
    console.log(this)
    console.log(event)
    container1.innerHTML = count++;
}
container1.onmousemove = debounce(dosomething, 300, true)//立即执行

增加可以设定函数的状态,ture为放抖,false为立刻执行后防抖。

此时代码的健壮性已经很不错了,,但还有优化的余地

返回值和取消操作的实现

明天写