防抖(debounce)和节流(throttle)区别详细讲解及案例练习

目录

  • 一、防抖
    • 1、概念
    • 2、理解
    • 3、应用场景
    • 4、封装防抖函数
  • 二、节流
    • 1、概念
    • 2、理解
    • 3、应用场景
    • 4、封装节流函数
  • 三、防抖与节流区别
  • 四、防抖与节流案例
    • 1、正常页面
    • 2、防抖案例
    • 3、节流案例
  • 五、插件

一、防抖

1、概念

防抖策略(debounce):当事件被触发后,延迟 n 秒后再执行回调,;若在n秒内又被触发,则重新计时。

2、理解

多次触发只执行一次,比如王者荣耀回城,只有经过8秒才能触发回城,8秒途中再次触发回城或中断,都需要重新等待8秒才能回城

3、应用场景

登录、发短信等按钮避免用户点击太快,导致发送了多次请求,需要防抖。

4、封装防抖函数

let debounce = function (handler,delay) {
    let timer=null;
    return function () {
        if(timer) clearTimeout(timer);
        timer = setTimeout(()=>{
            fn.apply(this,arguments)
        },delay)
    }
}

二、节流

1、概念

在规定的时间范围内不会重复触发回调,只有大于这个时间间隔才会触发,把频繁触发变为少量触发。

2、理解

一个周期只执行一次,比如王者荣耀技能,只有经过技能冷却时间,,才能再次使用

3、应用场景

① 鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;

② 懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费 CPU 资源;

③ 浏览器input搜索框展示下拉列表,需要节流,也可以使用防抖

4、封装节流函数

let throttle = function(handler,delay) {
	let timer = null;   
  	return function () {
       if(timer) return;
       timer = setTimeout(() => {
         fn.apply(this,arguments)
         timer = null
       })
   }
}

三、防抖与节流区别

名称 区别 举例
防抖 最后一次执行的是防抖 王者荣耀回城技能
节流 控制次数的是节流 英雄cd技能

通过对比防抖和节流函数,可以发现两者一个是return,一个是clearTimeout,为什么?
答:
防抖是触发间隔大于timer才会触发,所以每次在小于间隔time要清除定时器;

节流是不管time内触发多少次,只会每间隔time时间才会触发一次,所以用return

总结:防抖是限制操作,节流是减少操作

四、防抖与节流案例

1、正常页面

如果你在1秒内输入123,那它就会在1秒内分别执行输入1、2、3时的事件。

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>正常案例title>
head>

<body>
    <input type="text" id="input">
    <script>
        let input = document.getElementById("input");
        let span = document.createElement('span');
        let num = 0;
        input.addEventListener("input", inputEvent)
        //输入事件
        function inputEvent(e) {
            console.log(e, this)
            num++;//记录请求次数
            span.innerHTML = `

${num}次请求了接口

`
; document.body.appendChild(span); }
script> body> html>

2、防抖案例

如果在200ms内输入123,那它只会执行输入3时的事件。

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>防抖title>
head>

<body>
    <input type="text" id="input">
    <script>
        let input = document.getElementById("input");
        let span = document.createElement('span');
        let num = 0;
        input.addEventListener("input", debounce(inputEvent, 200))
        //输入事件
        function inputEvent(e) {
            console.log(e, this)
            num++;//记录请求次数
            span.innerHTML = `

${num}次请求了接口

`
; document.body.appendChild(span); } //防抖 function debounce(fn, delay) { //这里相当于定义了一个全局的timer let timer = null; return function () { //如果定时器存在,那就清掉,开启新的计时器 if (timer) { clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, arguments); }, delay); } }
script> body> html>

3、节流案例

如果你在一秒内输入123,那它只会执行输入1时的方法。

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>节流title>
head>
 
<body>
    <input type="text" id="input">
    <script>
        let input = document.getElementById("input");
        let span = document.createElement('span');
        let num = 0;
        input.addEventListener("input", throttle(inputEvent, 1000))
        //输入事件
        function inputEvent(e) {
            console.log(e, this)
            num++;//记录请求次数
            span.innerHTML = `

${num}次请求了接口

`
; document.body.appendChild(span); } //节流 function throttle(fn, delay) { //相当于在全局定义了一个timer let timer = null; return function () { //如果timer存在,直接结束函数 if (timer) { return } timer = setTimeout(() => { fn.apply(this, arguments); //指定时间结束后,将timer变成null,否则这个函数将一直不执行 timer = null }, delay); } }
script> body> html>

五、插件

第三方插件库:lodash
地址:https://www.lodashjs.com/

你可能感兴趣的:(JavaScript,javascript,前端,java)