来自 软件资讯 2019-10-04 13:44 的文章
当前位置: 威尼斯国际官方网站 > 软件资讯 > 正文

浅谈JS函数节流防抖,js函数的节流与防抖

一、防抖&节流

  在前端开发中有一部分用户行为会频繁的触发事件执行,而对于DOM的操作、资源加载等耗费性能的处理,很可能会导致界面卡顿,甚至浏览器奔溃。函数的节流与防抖就是为了解决类似需求而产生的。

  1)节流

    概念:函数的节流就是预定一个函数只有在大于等于执行周期时才会执行,周期内调用不会执行。好像一滴水只有积攒到一定重量才会落下一样。

    场景:窗口调整(resize)、页面滚动(scroll)、抢购疯狂点击(movedown)

    故事:阿里巴巴月饼门事件,中秋来临,阿里特意做了一个活动,抢月饼,但是每个人只能抢购一盒,有五位工程师写了js脚本,类似于12306的抢票软件,直接刷了一百多盒月饼,结果被开除了四个.其实对于他们来说并不是什么坏事,不知道有多少公司对他们敞开大门~那么如何解决这种问题呢,就用到了函数的节流

  1.1)案例(限时抢购)

    我写了这样一个简单的事件,如下

HTML:
1 <button id='show'>抢购</button>
2 <div id="box">0</div>  

JS:
1 let oBtn=document.getElementById('show')
2 let oBox=document.getElementById('box')
3 oBtn.onclick=function(){
4   oBox.innerText=parseInt(oBox.innerText)+1
5 }  

    当我点击时,每点击一次,数量增加一,点击越快,增加越快,效果图如下:

    图片 1

  1.2)脚本攻击:这种简单的数量增加很容易遭到脚本的攻击,从而造成很大的损失。代码如下

    for(let i=0;i<100;i++){oBtn.click()}

    效果图如下:

    图片 2

  1.3)如何解决(节流)

    上面并不是我们想要的结果,我们想要的是在规定时间内只能执行一次,比如1秒内只能执行一次.无论你点击多少次.

HTML:
1 <button id='show'>抢购</button>
2 <div id="box">0</div>

 JS:
 1 let oBtn=document.getElementById('show');
 2     let oBox=document.getElementById('box');
 3     /*
 4         handle:buy函数
 5         wait:规定在一秒钟内只能执行一次
 6     */
 7     function throttle (handle, wait) {
 8         let lastTime = 0;
 9         return function (e) {
10             let nowTime = new Date().getTime()
11             if (nowTime - lastTime > wait) {
12                 handle();
13                 lastTime = nowTime;
14             }
15         }
16     }
17     function buy(){
18         oBox.innerText = parseInt(oBox.innerText)+1
19     }
20     oBtn.onclick = throttle(buy, 1000)

    效果图如下:

图片 3

    这样不仅可以达到想要的效果,还可以阻止恶意脚本的攻击.

  

  2.防抖

    概念:函数防抖就是函数需要频繁触发情况时,只有足够空闲的时候,才会执行一次。好像公交司机会等人都上车后才会开车一样.

    场景:实时搜索(keyup)、拖拽(mousemove)

    2.1).案例(实时搜索)

      在之前看一下这个过程图,百度的实时搜索.

图片 4

 

      在搜索nba的时候,并不是每输入一个字符,都会想服务器请求一次,而是在输入完成后发出一次请求。

HTML:
1 <input type='text' id='ipt'/>

JS:
1 let oIpt = document.getElementById('ipt');
2 function ajax () {
3     console.log(this.value)
4 }
5 oIpt.oninput = ajax;

      效果图如下:

图片 5

    用户无论输入多快,都会发出请求,从而去加载服务器资源,对性能有很大的影响.

    2.3)解决(防抖)

 1 let oIpt = document.getElementById('ipt');
 2     let time = null;
 3     function debounce (handle, delay) {
 4         let time = null;
 5         return function () {
 6             let self = this,arg = arguments;
 7             clearTimeout(time);
 8             time = setTimeout(function () {
 9                 handle.apply(self,arg);  //this绑定
10             },delay)
11         }
12     }
13     function ajax (e) {
14         console.log(e,this.value)
15     }
16     oIpt.oninput = debounce(ajax, 1000)  //1s后发出请求

      效果图:图片 6

  这种方法可以解决多次请求的问题,对性能有很大的提高。

  喜欢的小伙伴点个关注哦~我会再接再厉的。

 

    

    

    

在前端开发中有一部分的用户行为会频繁的触发事件执行,而对于DOM操作、资源加载等耗费性能的处理,很可能导致界面卡顿,甚至浏览器的崩溃。函数节流(throttle)和函数防抖(debounce)就是为了解决类似需求应运而生的。

函数节流(throttle)

函数节流就是预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。好像水滴攒到一定重量才会落下一样。

场景:

  • 窗口调整(resize)
  • 页面滚动(scroll)
  • 抢购疯狂点击(mousedown)

实现:

function throttle(method, delay){
  var last = 0;
  return function (){
    var now = +new Date();
    if(now - last > delay){
      method.apply(this,arguments);
      last = now;
    }
  }
}

document.getElementById('throttle').onclick = throttle(function(){console.log('click')},2000);

underscore实现:

_.throttle = function(func, wait, options) {
  var context, args, result;
  var timeout = null;
  var previous = 0;
  if (!options) options = {};
  var later = function() {
    previous = options.leading === false ? 0 : _.now();
    timeout = null;
    result = func.apply(context, args);
    if (!timeout) context = args = null;
  };
  return function() {
    var now = _.now();
    if (!previous && options.leading === false) previous = now;
    //计算剩余时间
    var remaining = wait - (now - previous);
    context = this;
    args = arguments;
    //剩余时间小于等于0或者剩余时间大于等待时间(本地时间变动出现)
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = now;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    } else if (!timeout && options.trailing !== false) {
      timeout = setTimeout(later, remaining);
    }
    return result;
  };
};  

函数防抖(debounce)

本文由威尼斯国际官方网站发布于软件资讯,转载请注明出处:浅谈JS函数节流防抖,js函数的节流与防抖

关键词: