面试一面大概率问题:

  1. 什么是防抖,如何防抖?
  2. 什么是节流,如何节流?

一 目录

不折腾的前端,和咸鱼有什么区别

目录
一 目录
二 防抖
 2.1 手写防抖
 2.2 防抖利用
三 节流
 3.1 手写节流
 3.2 节流利用
四 防抖 + 节流

二 防抖

返回目录

防抖:工作频繁触发的状况下,只有工作触发的距离超过指定距离的时候,工作才会执行。

举例:

  1. 监听拖拽滚动条,而后频繁向下滚动信息,会变得很慢,很机灵。
  2. 点击提交表单后,用户在后果还没进去的时候反复触发。

简略来说:某件事你并不想它太过频繁触发,那么设置一个定时器,每次进来的时候都革除本来的定时器,而后从新开始计时。

2.1 手写防抖

返回目录
  1. 设置定时器
  2. 设置一个闭包,返回一个办法
  3. 如果重复进来,清空后面的定时器,再从新设置一遍
function debounce(fn) {  let timer = null;  return function() {    clearTimeout(timer);    timer = setTimeout(() => {      fn.call(this.arguments);    }, 1000);  }}

2.2 防抖利用

返回目录

联合实例:

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">  <meta http-equiv="X-UA-Compatible" content="ie=edge">  <title>防抖</title></head><body>  <button id="debounce">点我防抖!</button>  <script>    window.onload = function() {      // 1、获取这个按钮,并绑定事件      var myDebounce = document.getElementById("debounce");      myDebounce.addEventListener("click", debounce(sayDebounce));    }    // 2、防抖性能函数,承受传参    function debounce(fn) {      // 4、创立一个标记用来寄存定时器的返回值      let timeout = null;      return function() {        // 5、每次当用户点击/输出的时候,把前一个定时器革除        clearTimeout(timeout);        // 6、而后创立一个新的 setTimeout,        // 这样就能保障点击按钮后的 1000 毫秒距离内        // 如果用户还点击了的话,就不会执行 fn 函数        timeout = setTimeout(() => {          fn.call(this, arguments); // 修改 this 指向问题        }, 1000);      };    }    // 3、须要进行防抖的事件处理    function sayDebounce() {      console.log(this);      // ... 有些须要防抖的工作,在这里执行      console.log("防抖胜利!");    }  </script></body></html>

三 节流

返回目录

节流:指定工夫距离内只会执行一次工作。

举例:

  1. 你不想频繁为你女票买单,于是约好每月 1 号清空购物车
  2. 避免过快拖动滚动条,导致 JS 跟不上拖动频率,通过节流限度每秒触发监听的次数(固定工夫固定频率)

简略来说:年轻人要放弃一日三餐,法则作息,那就通过节流来限度。

3.1 手写节流

返回目录
  1. 设置一个标记
  2. 设置一个闭包,返回一个办法
  3. 如果反复进去的时候,标记曾经动了,那就组织程序进一步运行
  4. 如果定时器执行完了,设置这个标记为没动,容许下一次执行
function throttle(fn) {  let timer = true;  return function() {    if (!timer) {      return;    }    timer = false;    setTimeout(() => {      fn.call(this, arguments);      timer = true;    }, 1000);  }}

3.2 节流利用

返回目录

联合实例:

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">  <meta http-equiv="X-UA-Compatible" content="ie=edge">  <title>节流</title></head><body>  <button id="throttle">点我节流!</button>  <script>    window.onload = function() {      // 1、获取按钮,绑定点击事件      var myThrottle = document.getElementById("throttle");      myThrottle.addEventListener("click", throttle(sayThrottle));    }    // 2、节流函数体    function throttle(fn) {      // 4、通过闭包保留一个标记      let canRun = true;      return function() {        // 5、在函数结尾判断标记是否为 true,不为 true 则中断函数        if(!canRun) {          return;        }        // 6、将 canRun 设置为 false,避免执行之前再被执行        canRun = false;        // 7、定时器        setTimeout( () => {          fn.call(this, arguments);          // 8、执行完事件(比方调用完接口)之后,从新将这个标记设置为 true          canRun = true;        }, 1000);      };    }    // 3、须要节流的事件    function sayThrottle() {      console.log("节流胜利!");    }  </script></body></html>

四 防抖 + 节流

返回目录

防抖有时候因为触发太过频繁,导致一次响应都没有。

所以心愿固定的工夫必然给用户一个响应,于是就有了防抖 + 节流的操作。

  1. 设置 last 记录定时器开始的工夫
  2. 设置 timer 示意一个定时器
  3. 获取以后工夫 now
  4. 如果以后工夫 - 开始工夫小于延迟时间,那么就防抖
  5. 否则设置工夫到了,执行函数
function throttle(fn, delay) {  let last = 0, timer = null;  return function (...args) {    let now = new Date();    if (now - last < delay){      clearTimeout(timer);      setTimeout(function() {        last = now;        fn.apply(this, args);      }, delay);    } else {      // 这个时候示意工夫到了,必须给响应      last = now;      fn.apply(this, args);    }  }}

jsliang 的文档库由 梁峻荣 采纳 常识共享 署名-非商业性应用-雷同形式共享 4.0 国内 许可协定 进行许可。<br/>基于 https://github.com/LiangJunrong/document-library 上的作品创作。<br/>本许可协定受权之外的应用权限能够从 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 处取得。