防抖(debounce)

防抖的应用场景

  1. scroll事件滚动触发
  2. 搜索框输入查询
  3. 表单验证
  4. 按钮提交事件
  5. 浏览器窗口缩放,resize事件

防抖的原理

原理:n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

举例:
事件响应函数在一段时间后才执行,如果在这段事件内再次调用,则重新计算执行时间;当预定的时间内没有再次调用该函数,则执行dosomething函数。

<style>
    #container{
        width: 100%;
        height:200px;
        line-height: 200px;
        text-align: center;
        color:#fff;
        background-color: #444;
        font-size: 30px;
    }
</style>
<body>
    <div id="container"></div>
    //引入underscore库,其中的debounce可以实现防抖
    <script src="http://cdn.bootcss.com/underscore.js/1.9.1/underscore.js"></script>
    <script>
        let count = 0
        //演示时间是如何频繁发生的
        let container  = document.querySelector('#container')

        function doSomeThing(){
            //可能会做回调或者ajax请求
            container.innerHTML = count++;
        }
        //_.debounce(高阶函数)对doSomething函数进行包装,第一个参数为被包装函数的函数名,第二个参数为时间,表示多少毫秒后执行
        //第三个参数表示是否立即执行,如果设置true表示立即执行,默认值是不会立即执行container.onmousemove = _.debounce(doSomeThing,2000,true);
        container.onmousemove = _.debounce(doSomeThing,2000);
    </script>
</body>

防抖的分类

防抖分为立即防抖非立即防抖

  • 立即防抖:多次触发事件,第一次会立即执行函数,之后在设定wait时间内触发的事件无效,不会执行。

  • 非立即防抖:多次触发事件,只会在最后一次触发事件后等待设定的wait时间结束时执行一次。

手写防抖函数(debounce)

初步实现防抖函数:

index.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    #container{
        width: 100%;
        height:200px;
        line-height: 200px;
        text-align: center;
        color:#fff;
        background-color: #444;
        font-size: 30px;
    }
</style>
<body>
    <div id="container"></div>
    <!-- //引入debounce.js文件 -->
    <script src="./debounce.js"></script>
</body>
</html>

js文件:

//防抖的函数
//这里用到了闭包
function debounce(func,wait,immediate){
    let timeout;
    return function(){
        //改变执行函数内部this的指向,让this指向container
        let context = this;
        //参数
        let args = arguments;
        clearTimeout(timeout)//只清除定时器,不清除timeout的值
        if(immediate){
            //立即执行:多次触发事件,第一次会立即执行函数,之后在设定wait时间内触发的事件无效,不会执行。
            //callNow来记录是否立即执行,callNow为true立即执行
            let callNow = !timeout;
            //wait时间内(timeout有值,callNow为false)不会立即执行
            //wait时间到了(timeout值置为null,callNow为true)立即执行
            timeout = setTimeout(()=>{
                timeout = null;
            },wait);
            if(callNow){
                func.apply(context,args)
            }
        }else{
            //非立即执行:多次触发事件,只会在最后一次触发事件后等待设定的wait时间结束时执行一次。
            timeout = setTimeout(()=>{
                func.apply(context,args)
            },wait)
        }
    }
}
let count = 0;
//演示时间是如何频繁发生的
let container = document.querySelector("#container");

function doSomeThing() {
  //可能会做回调或者ajax请求
  container.innerHTML = count++;
}
container.onmousemove = debounce(doSomeThing, 300,true);

防抖函数中返回值和取消操作的实现:

index.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    #container{
        width: 100%;
        height:200px;
        line-height: 200px;
        text-align: center;
        color:#fff;
        background-color: #444;
        font-size: 30px;
    }
</style>
<body>
    <div id="container"></div>
    <button id="btn">取消防抖</button>
    <!-- //引入debounce.js文件 -->
    <script src="./debounce.js"></script>
</body>
</html>

js文件:

//防抖的函数
function debounce(func,wait,immediate){
    var timeout,result;
    var debounced = function(){
        //改变执行函数内部this的指向,让this指向container
        var context = this;
        //参数
        var args = arguments;
        if(timeout) clearTimeout(timeout);
        if(immediate){          
            var callNow = !timeout;
            timeout = setTimeout(()=>{
                timeout = null;
            },wait);
            if(callNow){
                result = func.apply(context,args)
            }
        }else{
            timeout = setTimeout(()=>{
                func.apply(context,args)
            },wait)
        }
        return result;
    }
    //取消防抖
    debounced.cancel = function(){
        clearTimeout(timeout)
        //防止内存泄露
        timeout = null;
    }
    return debounced;
}
let count = 0;
//演示时间是如何频繁发生的
let container = document.querySelector("#container");
let btn = document.querySelector('#btn')
function doSomeThing() {
  //可能会做回调或者ajax请求
  container.innerHTML = count++;
  return '想要的结果'
}
let doSome = debounce(doSomeThing,1000);
//点击按钮,取消防抖
btn.onclick = function(){
    doSome.cancel()
}
//给container绑定鼠标移动事件
container.onmousemove = doSome;

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
lodash是一个JavaScript工具,提供了许多实用的函数和工具来简化JavaScript开发。其中之一是`debounce`函数,用于创建一个防抖函数。 防抖函数是指在一定时间内连续触发的事件只执行一次,常用于处理频繁触发的事件,比如浏览器窗口的resize事件、输入框的输入事件等。防抖函数可以避免频繁触发导致的性能问题。 在lodash中,`debounce`函数的用法如下: ```javascript _.debounce(func, wait, options) ``` - `func`:要执行的函数。 - `wait`:等待时间(毫秒),即事件触发后,等待多长时间执行函数。 - `options`:可选参数对象,可以设置更多的选项,比如`leading`和`trailing`。 `leading`和`trailing`是两个布尔值选项: - `leading`:默认为`false`,表示禁用首次执行。如果设置为`true`,则第一次触发事件时立即执行函数。 - `trailing`:默认为`true`,表示在最后一次触发事件后,再等待一段时间执行函数。如果设置为`false`,则最后一次触发事件后不再执行函数。 下面是一个简单的示例,演示如何使用`lodash`的`debounce`函数: ```javascript function saveToServer() { // 模拟发送数据到服务器的操作 console.log("Saving data to server..."); } var debouncedSave = _.debounce(saveToServer, 1000); // 模拟触发事件 debouncedSave(); debouncedSave(); debouncedSave(); // 1秒后,只会执行一次保存操作 ``` 在上述代码中,`saveToServer`函数会被防抖处理,只有在最后一次触发事件后等待1秒后,才会执行一次保存操作。 希望这个例子能够帮助您理解`lodash`中的`debounce`函数。如果您有任何其他问题,请随时提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值