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> 复制代码
效果图如下:
一输入内容,就会一直执行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秒执行方法,点击看看使用效果:
第二个例子
立刻执行
有这样一个需求,鼠标移动事件,移动到内容上,立即执行函数.
根据这段表述,我们可以写的代码:
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秒后执行方法,看看使用效果:
完善功能增加取消防抖功能
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秒,当点击取消防抖后立即执行了,看看使用效果:
参考地址:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- immer.js 实战讲解
- 实战大数据平台开发架构讲解
- 实战讲解:如何用Python搭建一个服务器
- Hive SQL 综合应用案例实战及多项性能指标深入讲解-DW商业环境实战
- 跨域认证解决方案-JSON WEB TOKEN讲解与实战
- 【白瞟版】分布式商城系统,最牛逼技术栈,实战讲解407个视频,含源码
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。