JavaScript函数防抖与函数节流的定义及使用详解

目录
  • 一、函数防抖(Debouncing)
    • 1、基本概念
    • 2、算法思想
    • 3、代码实现
    • 4、使用场景
  • 二、函数节流(Throlle)
    • 1、基本概念
    • 2、算法思想
    • 3、代码实现
    • 4、使用场景

一、函数防抖(Debouncing)

1、基本概念

在触发事件后的规定时间内只能执行一次,如果在规定时间内又触发了该事件。则会重新开始计算规定时间;

2、算法思想

(1)首先定义一个函数,函数进入页面立即执行一次,且永远执行最新的一次;

(2)返回一个匿名函数;

(3)在匿名函数里使用计时器setTimeout设置规定时间;

(4)在使用clearTimeout来清除上一次的函数调用;

(5)在事件中调用该函数;

(6)必须返回函数,因为事件只能调用函数;

3、代码实现

//功能:防抖函数
    function debounce(callback,time = 300){
        let t;
        //返回一个匿名函数
        return function(){
            clearTimeout(t);//清除定时器
            t = setTimeout(callback,time);//设置定时器
        }
    }
    //在onscroll事件中调用防抖函数
    window.onscroll = debounce(function(){
        console.log("调用了1次");
    },500);

onscroll事件为滚动条事件  属于window对象

callback为回调函数

4、使用场景

防抖函数就是为了防止用户进行一些频繁的点击事件、输入文字或者滚动事件时,对应绑定的事件发生多次的场景,这些事件的触发频率很高,不做限制的话可能一秒执行几十次甚至几百次,会造成不必要的浪费。

下面用一个在网页中经常遇到的回到顶部案例说明

代码:

<!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>
    *{
        margin: 0;
        padding: 0;
    }
    body{
        height: 5000px;
        background-color: aqua;
    }
    img{
        position: fixed;
        bottom: 100px;
        right: 50px;
        display: none;
    }
</style>
<body>
    <img id="returntop" src="./img/return.png" alt="">
</body>
<script>
    //函数防抖
    function delbounce(callback,time = 300){
        let t;
        return function(){
            clearTimeout(t);
            t = setTimeout(callback,time);
        }
    }
    //绑定滚动条事件
    window.onscroll = delbounce(returntop,200);
    //onscroll   滚动条事件  属于window事件  不写到标签里
     function returntop(){
        //距离浏览器顶部的距离
        console.log("调用了1次");
        let num = document.body.scrollTop || document.documentElement.scrollTop;
        // console.log(parseInt(num));
        //判断隐藏和出现
        if(parseInt(num) > 400){
            document.getElementById("returntop").style = "display:block";
        }else{
            document.getElementById("returntop").style = "display:none";
        }
    }
</script>
</html>

效果:

分析:大大减少了函数的调用次数,减少了对计算机资源的浪费等等;

二、函数节流(Throlle)

1、基本概念

函数节流和函数防抖恰好相反,规定在一个单位时间内,只能调用一次函数,如果在这个规定时间内对此调用函数,只能有一次被调用,相当于子啊这个规定时间内永远只会执行第一次。

2、算法思想

(1)获取刚进入页面的时间戳;

(2)获取事件开始发生的时间戳;

(3)如果相隔的时间大于设定的时间,则继续下一次调用;

(4)更新上一次调用的时间,永远执行第一次;

3、代码实现

 //功能:函数节流  永远执行第一次
    function throlle(callback,time){
        let lasttime = new Date().getTime();//获取刚进入页面时的时间戳
        return function(){
            let nowtime = new Date().getTime();//获取滚动条开始滑动的时间戳
            if (nowtime - lasttime > time){//如果时间间隔大于设定的时间  则继续下一次调用
                callback();
                lasttime = nowtime;//更新上一次的时间戳
            }
        }
    }
    window.onscroll = throlle(function(){
        console.log("调用了1次");
    },500);

getTime():用来获取当前的时间戳

4、使用场景

函数节流可以运用于所有的数据请求、按钮和下拉刷新等等。

用一个登录按钮的使用的案例来说明

代码:

<!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>
    *{
        margin: 0;
        padding: 0;
    }
    body{
        background: url(./img/login.gif) no-repeat;
        background-size: 100%;
    }
    div.login{
        width: 500px;
        height: 360px;
        background-color: rgba(0, 0, 0, 0.2);
        border-radius: 10px;
        margin: 50px auto;
    }
    div.login h1{
       padding-top: 10px;
       padding-bottom: 10px;
       text-align: center;
       color: white;
    }
    div.email,div.tel,div.pwd{
        margin-left: 17px;
    }
    div.login div.email input,div.login div.tel input,div.login div.pwd input{
        width: 450px;
        height: 45px;
        padding-left: 11px;
        margin: 8px 0;
    }
    div.login div.btn button{
        width: 450px;
        height: 40px;
        color: white;
        background-color: rgba(0, 0, 0, 0.2);
        border-radius: 20px;
        text-align: center;
        margin-top: 10px;
        margin-left: 20px;
        line-height: 40px;
        border: 0;
    }
    div.login div.btn button:hover{
        cursor: pointer;
        background-color:rgba(0, 0, 0, 0.4) ;
    }
    div.login #emailarr,#telarr,#pwdarr{
        color: red;
        font-size: 12px;
    }
</style>
<body>
    <div class="login">
        <h1>后台管理系统</h1>
        <div class="email">
            <input type="email" id="email" onblur="isEamil()" placeholder="请输入邮箱..." required><br>
            <div id="emailarr"></div>
        </div>
        <div class="tel">
            <input type="tel" pattern="^1([358][0-9]|4[456789]|66|7[0135678]|9[189])\d{8}$"
             id="tel" onblur="isTel()" placeholder="请输入电话号码..." required><br>
            <div id="telarr"></div>
        </div>
        <div class="pwd">
            <input type="password" pattern="^[0-9a-zA-Z]{6,12}" onblur="isPwd()" id="pwd" placeholder="请输入密码..." required><br>
            <div id="pwdarr"></div>
        </div>
        <div class="btn">
            <button id="btn" disabled>登录</button>
        </div>
    </div>
</body>
<script>
    //功能:表单验证
    let emailState = false;
    let telState = false;
    let pwdState = false;
    //验证邮箱格式是否正确
    function isEamil(){
        let email = document.getElementById("email");
        if(email.validity.valueMissing){
            email.style = "border:2px red solid";
            document.getElementById("emailarr").innerHTML = "* 邮箱不能为空!";
            emailState = false;
            isState();
            return false;
        }
        if(email.validity.typeMismatch){
            email.style = "border:2px red solid";
            document.getElementById("emailarr").innerHTML = "* 请输入正确的邮箱!";
            emailState = false;
            isState();
            return false;
        }

        email.style = "border:2px green solid";
        document.getElementById("emailarr").innerHTML = "";
        emailState = true;
        isState()
        return true;

    }
    //验证电话号码格式是否正确
    function isTel(){
        let tel = document.getElementById("tel");
        if(tel.validity.valueMissing){
            email.style = "border:2px red solid";
            document.getElementById("telarr").innerHTML = "* 电话号码不能为空!";
            telState = false;
            isState();
            return false;
        }

        if(tel.validity.patternMismatch){
            tel.style = "border:2px red solid";
            document.getElementById("telarr").innerHTML = "* 请输入正确的电话号码!";
            telState = false;
            isState();
            return false;
        }

        tel.style = "border:2px green solid";
        document.getElementById("telarr").innerHTML = "";
        telState = true;
        isState()
        return true;

    }
    //验证密码格式是否正确
    function isPwd(){
        let pwd = document.getElementById("pwd");
        if(pwd.validity.valueMissing){
            pwd.style = "border:2px red solid";
            document.getElementById("pwdarr").innerHTML = "* 密码不能为空!";
            pwdState = false;
            isState();
            return false;
        }

        if(pwd.validity.patternMismatch){
            pwd.style = "border:2px red solid";
            document.getElementById("pwdarr").innerHTML = "* 请输入正确的密码!";
            pwdState = false;
            isState();
            return false;
        }
        pwd.style = "border:2px green solid";
        document.getElementById("pwdarr").innerHTML = "";
        pwdState = true;
        isState()
        return true;
    }
    //判断三个结果是否都为true  removeAttribute()  删除获取的的某个节点的对应属性
    function isState(){
        if(emailState && telState && pwdState){
            document.getElementById("btn").removeAttribute("disabled");
        }else{
            document.getElementById("btn").setAttribute("disabled","disabled");//设置属性
        }
    }

    //登陆成功
    function login(){
        console.log("函数调用1次");
        //将数据发给后台处理
        //后台返回两种结果 error  success
        //将成功后的用户信息进行本地存储  userid  token
        // let userid = 123456;
        // localStorage.setItem("userid",userid);
        // location.href = "./logininfo.html";
    }

    document.getElementById("btn").onclick = throlle(login,5000);

    function throlle(callback,time){
        let lasttime = new Date().getTime();
        return function(){
            let nowtime = new Date().getTime();
            if (nowtime - lasttime > time){//在time时间段  不能在调用函数
                callback();
                lasttime = nowtime;
            }
        }
    }
</script>
</html>

效果:

分析:在规定时间不允许在点击登录按钮 超过规定时间以后才能继续点击,进行下一次登录;

到此这篇关于JavaScript函数防抖与函数节流的定义及使用详解的文章就介绍到这了,更多相关JavaScript函数防抖 节流内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 浅析JavaScript 函数防抖和节流

    函数防抖和节流都是对高频动作触发回调函数的一个优化,实现方式上有类似之处.先从使用场景做个区分. 防抖使用场景: 表单输入框校验 提交按钮避免重复提交 节流使用场景: scroll,mousemove,resize等 函数防抖(debounce) 表单输入框校验在用户不停的打字输入时并不需要向后台校验文本,只有当用户停下来一定时间后,这时候默认用户已经输入完毕了可以开始向后台提交文本了. 表单的提交按钮被用户多次连续点击时,显然并不需要每次点击都提交表单.仅在用户不点击之后,把最后一次的点击操作

  • 浅谈JavaScript节流和防抖函数

    概念 节流函数 间隔固定的时间执行传入的方法 目的是防止函数执行的频率过快,影响性能.常见于跟滚动,鼠标移动事件绑定的功能. 防抖函数 对于接触过硬件的人也许更好理解,硬件按钮按下时,由于用户按住时间的长短不一,会多次触发电流的波动,加一个防抖函数就会只触发一次,防止了无意义的电流波动引起的问题. 按键防反跳(Debounce)为什么要去抖动呢?机械按键在按下时,并非按下就接触的很好,尤其是有簧片的机械开关,会在接触的瞬间反复的开合多次,直到开关状态完全改变. 应用在前端时,常见的场景是,输入框

  • JS中节流和防抖函数的实现及区别示例

    目录 引言 一.概念 二.实现 三.区别 四.Lodash 4-1.throttle 4-2.debounce 五.使用场景 六.总结 引言 在前端开发中,经常和DOM.BOM打交道,例如:窗口的resize.scroll,输入框内容校验,按钮点击等等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕. 此时我们可以采用throttle(节流)和debounce(防抖)的方式来减少调用频率,提高性能的同时又不影响实际效果. 一.概念 函数节流( throttle

  • JavaScript中函数的防抖与节流详解

    目录 一.函数的节流 1.1定义 1.2解决方法 1.3案例演示 1.3.1 代码演示 1.3.2 运行结果 1.3.3 添加函数节流操作 1.3.4 运行结果 二.函数的防抖 2.1 定义 2.2 解决方法 2.3 案例演示 2.3.1 代码展示 2.3.2 运行结果 2.3.3添加函数防抖操作 2.3.4 运行结果 总结 一.函数的节流 1.1 定义 同时触发多次函数执行,执行的是相同内容,要求只执行第一次请求. 例如scroll事件,鼠标滚动一次触发多次函数执行,只需要执行一次. 1.2

  • 如何理解JS函数防抖和函数节流

    概述 函数防抖和函数节流都是定义一个函数,该函数接收一个函数作为参数,并返回一个添加了防抖或节流功能后的函数. 因此可以将函数防抖和函数节流看作是一个函数工厂,负责对传进来的函数进行相应的加工改造,然后产出一个新的带有某种功能的函数. 函数防抖是某一时间内只执行一次,而函数节流是间隔时间执行 假如有这样一个场景:在某一页面,有一个按钮是 "加载更多",这个按钮的作用就是使用 ajax 从后端服务器请求更多的数据展示在页面,我们都知道,ajax 请求的响应是一个异步的,会存在一定的响应时

  • JS防抖节流函数的实现与使用场景

    目录 一.什么是函数防抖 1.为什么需要函数防抖? 2.函数防抖的要点 3.函数防抖的实现 4.函数防抖的使用场景 二.什么是函数节流 1.函数节流的要点 2.函数节流的实现 3.函数节流的使用场景 总结 一.什么是函数防抖 概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间. 1.为什么需要函数防抖? 前端开发过程中,有一些事件,常见的例如,onresize,scroll,mousemove ,

  • JavaScript函数防抖与函数节流的定义及使用详解

    目录 一.函数防抖(Debouncing) 1.基本概念 2.算法思想 3.代码实现 4.使用场景 二.函数节流(Throlle) 1.基本概念 2.算法思想 3.代码实现 4.使用场景 一.函数防抖(Debouncing) 1.基本概念 在触发事件后的规定时间内只能执行一次,如果在规定时间内又触发了该事件.则会重新开始计算规定时间: 2.算法思想 (1)首先定义一个函数,函数进入页面立即执行一次,且永远执行最新的一次: (2)返回一个匿名函数: (3)在匿名函数里使用计时器setTimeout

  • python函数声明和调用定义及原理详解

    这篇文章主要介绍了python函数声明和调用定义及原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 函数是指代码片段,可以重复调用,比如我们前面文章接触到的type()/len()等等都是函数,这些函数是python的内置函数,python底层封装后用于实现某些功能. 一.函数的定义 在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回:

  • JavaScript函数之call、apply以及bind方法案例详解

    总结 1.相同点 都能够改变目标函数执行时内部 this 的指向 方法的第一个参数用于指定函数执行时内部的 this 值 支持向目标函数传递任意个参数 若不向方法的第一个参数传值或者传递 undefined.null,则在 JavaScript 正常模式下,目标函数内部的 this 指向 window 对象,严格模式下,分别指向 undefined.null. 2.区别 apply() 方法可接收两个参数,而 call() 和 bind() 方法则可接收多个参数. apply() 方法向目标函数

  • Python学习之函数的定义与使用详解

    目录 函数的定义 函数的分类 函数的创建方法-def 函数的返回值-return return与print的区别 函数的传参 必传参数 默认参数 不确定参数(可变参数) 参数规则 函数小练习 函数的参数类型定义 全局变量与局部变量 全局变量 局部变量 global关键字 递归函数 递归函数的定义方法 递归函数的说明 lambda-匿名函数 函数练习 函数的定义 什么是函数? — > 函数是具有某种特定功能的代码块,可以重复使用(在前面数据类型相关章节,其实已经出现了很多 Python 内置函数了

  • Go语言学习之函数的定义与使用详解

    目录 1.函数定义 2.多值返回 3.引用传递 4.函数作为实参使用 5.匿名函数 1.函数定义 函数的定义和java一样,使用{}进行包裹,并且要明确入参类型以及返回类型. 样例代码如下: func min(num1, num2 int) int { if num1 <= num2 { return num1 } else { return num2 } } func main() { fmt.Printf("max = %d\n", min(10, 12)) } 执行结果 m

  • C语言函数基础教程分类自定义参数及调用示例详解

    目录 1.  函数是什么? 2.  C语言中函数的分类 2.1 库函数 2.1.1 为什么要有库函数 2.1.2 什么是库函数 2.1.3 主函数只能是main()吗 2.1.4常见的库函数 2.2 自定义函数 2.2.1自定义函数是什么 2.2.2为什么要有自定义函数 2.2.3函数的组成 2.2.4 举例展示 3. 函数的参数 3.1 实际参数(实参) 3.2  形式参数(形参) 4. 函数的调用 4.1 传值调用 4.2  传址调用 4.3 练习 4.3.1. 写一个函数判断一年是不是闰年

  • Kotlin常用函数let,with,run,apply用法与区别案例详解

    在kotlin编程中let.with.run.apply这些函数使用率是非常高的,有时候可以通用,差别很小,但如果能记住他们的不同点,可以更加合理的选择使用. 在这之前首先要了解一下Lambda表达式的一些规则,这会帮助你理解使用这些函数的时候有没有( )可不可以用it代替参数等.因为这些函数的最后一个参数都是lambda. 如何理解lambda呢?可以把lambda理解为就是一个对象,但这个对象比较特殊,它是一段代码,既然是对象就可以作为函数的参数使用.这种对象称为函数对象. lambda表达

  • JavaScript策略模式利用对象键值的映射关系详解

    目录 引言 1.策略模式的极简实现 2.策略模式的简单案例 (1)工具函数 (2)提示样式 总结 引言 策略模式指的是,定义一系列的算法,把它们一个个的封装起来,通过传递一些参数,使他们可以相互替换. 举个周末从家去咖啡馆的例子: 从家去咖啡馆,有跑步.骑行和漫步的方式.也就是说,从家到咖啡馆,有三种策略可选择. 1.策略模式的极简实现 通过对象的键值映射关系,定义策略和具体实现之间的关系: var strategies = { A: xxx, B: yyy, C: zzz } 其中,A.B和C

  • JavaScript算法系列之快速排序(Quicksort)算法实例详解

    "快速排序"的思想很简单,整个排序过程只需要三步: (1)在数据集之中,选择一个元素作为"基准"(pivot). (2)所有小于"基准"的元素,都移到"基准"的左边:所有大于"基准"的元素,都移到"基准"的右边. (3)对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止. 举例来说,现在有一个数据集{85, 24, 63, 45,

随机推荐