<!DOCTYPE html>
<html lang="zh-cmn-Hans">

<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="IE=edge, chrome=1">
<title>debounce</title>
<style>
#container{
width: 100%; height: 200px; line-height: 200px; text-align: center; color: #fff; background-color: #444; font-size: 30px;
}
</style>
</head>

<body>
<div id="container"></div>
<script src="debounce.js"></script>
</body>

</html>

debounce.js 文件的代码如下:

var count = 1;
var container = document.getElementById('container');

function getUserAction() {
container.innerHTML = count++;
};

container.onmousemove = getUserAction;

触发事件,但是我一定在事件触发 n 秒后才执行,如果你在一个事件触发的 n 秒内又触发了这个事件,那我就以新的事件的时间为准,n 秒后才执行,总之,就是要等你触发完事件 n 秒内不再触发事件,

// 第一版
function debounce(func, wait) {
var timeout;
return function () {
clearTimeout(timeout)
timeout = setTimeout(func, wait);
}
}

container.onmousemove = debounce(getUserAction, 1000);

如果我们在 getUserAction 函数中 console.log(this),在不使用 debounce 函数的时候,this 的值为:

<div id="container"></div>

但是如果使用我们的 debounce 函数,this 就会指向 Window 对象!

所以我们需要将 this 指向正确的对象。

// 第二版
function debounce(func, wait) {
var timeout;

return function () {
var context = this;

clearTimeout(timeout)
timeout = setTimeout(function(){
func.apply(context)
}, wait);
}
}

event 对象

JavaScript 在事件处理函数中会提供事件对象 event,我们修改下 getUserAction 函数:

function getUserAction(e) {
console.log(e);
container.innerHTML = count++;
};

JavaScript 在事件处理函数中会提供事件对象 event,我们修改下 getUserAction 函数:

function getUserAction(e) {
console.log(e);
container.innerHTML = count++;
};

// 第三版
function debounce(func, wait) {
var timeout;

return function () {
var context = this;
var args = arguments;

clearTimeout(timeout)
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}

返回值

// 第四版
function debounce(func, wait) {
var timeout, result;

return function () {
var context = this;
var args = arguments;

clearTimeout(timeout)
timeout = setTimeout(function(){
result = func.apply(context, args)
}, wait);

return result;
}
}

我们修复了三个小问题:

  1. this 指向
  2. event 对象
  3. 返回值

立刻执行

我不希望非要等到事件停止触发后才执行,我希望立刻执行函数,然后等到停止触发n秒后,才可以重新触发执行。

// 第五版
function debounce(func, wait, immediate) {

var timeout, result;

return 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(){
result = func.apply(context, args)
}, wait);
}

return result;
}
}

取消

// 第六版
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(){
result = func.apply(context, args)
}, wait);
}
return result;
};

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

return debounced;
}

JavaScript 函数防抖的更多相关文章

  1. 深入理解javascript函数进阶系列第三篇——函数节流和函数防抖

    前面的话 javascript中的函数大多数情况下都是由用户主动调用触发的,除非是函数本身的实现不合理,否则一般不会遇到跟性能相关的问题.但在一些少数情况下,函数的触发不是由用户直接控制的.在这些场景 ...

  2. javaScript函数节流与函数防抖

    javaScript函数节流与防抖之区别 函数防抖(debounce)与函数节流(throttle)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟.假死或卡顿 ...

  3. JavaScript函数节流和函数防抖之间的区别

    一.概念解释  函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段.  大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...

  4. [JavaScript] 函数节流(throttle)和函数防抖(debounce)

    js 的函数节流(throttle)和函数防抖(debounce)概述 函数防抖(debounce) 一个事件频繁触发,但是我们不想让他触发的这么频繁,于是我们就设置一个定时器让这个事件在 xxx 秒 ...

  5. 函数节流和函数防抖JavaScript实现

    函数节流 function throttle(fn, delay = 1000) { let Running = false; return function () { if (Running) { ...

  6. 【javascript】js中的函数节流和函数防抖

    一.概念解释  函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段.  大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...

  7. JavaScript中函数防抖、节流

    码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14565642.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...

  8. js高阶函数应用—函数防抖和节流

    高阶函数指的是至少满足下列两个条件之一的函数: 1. 函数可以作为参数被传递:2.函数可以作为返回值输出: javaScript中的函数显然具备高级函数的特征,这使得函数运用更灵活,作为学习js必定会 ...

  9. 微信小程序:防止多次点击跳转(函数节流)和防止表单组件输入内容多次验证(函数防抖)

    一.函数节流(throttle) **函数节流:一个函数执行一次后,只有大于设定的执行周期后才会执行第二次**.有个需要频繁触发函数,出于优化性能角度,在规定时间内,只让函数触发的第一次生效,后面不生 ...

随机推荐

  1. 爱好-超级IP:超级IP

    ylbtech-爱好-超级IP:超级IP  IP,是Intellectual Property的缩写,字面粗译为“知识产权”,特指具有长期生命力和商业价值的跨媒介内容运营.一个具有可开发价值的真正的I ...

  2. curl发json

    linux 模拟post请求 curl -X POST \ -H "Content-Type: application/json" \ -H "token:GXJP1cl ...

  3. TensorFlow学习笔记4-线性代数基础

    TensorFlow学习笔记4-线性代数基础 本笔记内容为"AI深度学习".内容主要参考<Deep Learning>中文版. \(X\)表示训练集的设计矩阵,其大小为 ...

  4. JavaScript 开发的 睡眠状况自测(SRSS)

    Javascript 开发睡眠状况自测程序,手记!2019.11.13日... <script>//初始化fbox = new Findpair('fbox','output');fbox ...

  5. STL 迭代器适配器(iterator adapter)

    iterator adapter graph LR iterator --- reverse_iterator iterator --- Insert_iterator iterator --- io ...

  6. [Git] 013 远程仓库篇 第零话 使用前的一些配置

    0. 前言 本地仓库和 GitHub 上的远程仓库之间的传输是通过 "SSH" 加密的,所以使用前需要进行一些设置 这回的任务 设置"身份象征" 创建 &quo ...

  7. 从SVN下检出项目内容【步骤】

    1.新创建一个新的工作环境,然后new--->other--->SVN 2.点击Next,然后进行检出项目的操作,如下图所示: 3.再点击Next,进行输入指定的url地址,从指定的url ...

  8. hdu-4292.food(类dining网络流建图)

    Food Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. HDUSTOJ-1558 Flooring Tiles(反素数)

    1558: Flooring Tiles 时间限制: 3 Sec  内存限制: 128 MB提交: 59  解决: 36[提交][状态][讨论版] 题目描述 You want to decorate ...

  10. Bloxorz I (poj3322) (BFS)

    [题目描述] It's a game about rolling a box to a specific position on a special plane. Precisely, the pla ...