js 防抖实战讲解

栏目: JavaScript · 发布时间: 5年前

内容简介:在前端开发中会遇到一些频繁的事件触发,比如:window 的 resize、scrollmousedown、mousemove

在前端开发中会遇到一些频繁的事件触发,比如:

window 的 resize、scroll

mousedown、mousemove

keyup、keydown

……

为此,我们举个示例代码来了解事件如何频繁的触发:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>频繁触发例子</title>
</head>
<body>
	 <input id="search" type="text" placeholder="请输入要查询的内容">
	 <script>
	  	 var search = document.getElementById('search');
			function getUserAction() {
			   console.log('执行查询操作',+new Date());
			};

	    search.addEventListener('keyup', getUserAction)
	 </script>
</body>
</html>
复制代码

效果图如下:

js 防抖实战讲解

一输入内容,就会一直执行getUserAction 函数!

因为这个例子很简单,所以浏览器完全反应的过来,可是如果是复杂的回调函数或是 ajax 请求呢?假设 1 秒触发了 10 次,每个回调就必须在 1000 / 10 = 10ms 内完成,否则就会有卡顿出现。

为了解决这个问题,我们可以使用防抖

防抖原理

在事件被触发n秒后,再去执行回调函数。如果n秒内该事件被重新触发,则重新计时。结果就是将频繁触发的事件合并为一次,且在最后执行。

第一个例子

代码如下:

var search = document.getElementById('search');
function getUserAction(e) {
    console.log(e);
    console.log('执行查询操作',+new Date());
  };

function debounce(func, wait) {
    var timeout;
    return args => {
      if (timeout) clearTimeout(timeout) 
      timeout = setTimeout(func, wait);
    }
}

const debounceAjax = debounce(getUserAction, 1000)

subBtn.addEventListener('keyup', debounceAjax)
复制代码

输入后1秒执行方法,一直输入以输入完为准,1秒执行方法,点击看看使用效果:

js 防抖实战讲解

第二个例子

立刻执行

有这样一个需求,鼠标移动事件,移动到内容上,立即执行函数.

根据这段表述,我们可以写的代码:

function debounce(func, wait, immediate) {
    var timeout;
    return args => {
        let context = this;
        if (timeout) clearTimeout(timeout) 
        if (immediate) {
            // 如果已经执行过,不在执行
            let callNow = !timeout;
            timeout = setTimeout(function() {
                timeout = null;
            },wait) 
          if (callNow) func.call(context, args)
        } else {
            timeout = setTimeout(() => {
                func.call(context, args)
            },wait)
        }
    }
}
复制代码

debounce(getUserAction, 1000, true)

鼠标移动到内容上立即执行方法,重复移动以最后一次移动为准1秒后执行方法,看看使用效果:

js 防抖实战讲解

完善功能增加取消防抖功能

function debounce(func, wait, immediate) {
    var timeout,result;
    var debounced =  function() {
      var context = this;
      var args = arguments;

      if (timeout) clearTimeout(timeout);
      if (immediate) {
        // 如果已经执行过,不再执行
        var callNow = !timeout;
        timeout = setTimeout(function() {
          timeout = null;
        }, wait)
        if (callNow) result = func.apply(context, args)
      } else {
        timeout = setTimeout(function() {
          func.apply(context, args)
        }, wait);
      }

      return result;
    }

    debounced.cancel = function() {
    	  clearTimeout(timeout);
    	  timeout = null;
    }

    return debounced;
  }
复制代码

执行代码:

var setUseAction = debounce(getUserAction, 1000, true);
  container.onmousemove = function() {
    var res = setUseAction();
    console.log(res)
  }

  document.getElementById("button").addEventListener('click', function() {
    setUseAction.cancel();
  })
复制代码

设置时间间隔较大10秒,当点击取消防抖后立即执行了,看看使用效果:

js 防抖实战讲解

参考地址:

github.com/mqyqingfeng…


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

引爆点

引爆点

[美] 马尔科姆·格拉德威尔 / 钱清、覃爱冬 / 中信出版社 / 2006-1 / 29.80元

这本书是《纽约客》杂志专职作家马尔科姆·格拉德威尔的一部才华横溢之作。他以社会上突如其来的流行风潮研究为切入点,从一个全新的角度探索了控制科学和营销模式。他认为,思想、行为、信息以及产品常常会像传染病爆发一样,迅速传播蔓延。正如一个病人就能引起一场全城流感;如果个别工作人员对顾客大打出手,或几位涂鸦爱好者管不住自己,也能在地铁里掀起一场犯罪浪潮;一位满意而归的顾客还能让新开张的餐馆座无虚席。这些现......一起来看看 《引爆点》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

随机密码生成器
随机密码生成器

多种字符组合密码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具