-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
防抖(debounce)函数的作用是什么?有哪些应用场景,请实现一个防抖函数。 #10
Comments
做一个类比,假设你和你的朋友chatty通过微信聊天,她非常的健谈,那么你有如下几种方式来处理她的消息:
在浏览器中,有很多事件比如window的onresize 鼠标的mousemove 以及滚轮事件wheel等,他们触发的很频繁,这个时候函数没必要一直执行。函数防抖就是让事件触发的n秒内只执行一次,如果连续触发就重新计算时间. function debounce(fn, delay, immediate) {
let timer = null;
return function() {
clearTimeout(timer); //重新计算时间
let context = this;
let args = arguments;
if (!timer && immediate) {
fn.apply(context, args);
}
timer = setTimeout(function() {
if (!immediate) {
fn.apply(context, args);
} else {
timer = null;
}
}, delay)
}
} |
防抖(debounce)在n秒内函数只被执行一次,如果在这个时间内再次被触发,则需要再次计算时间。
|
在频繁触发某些事件,导致大量的计算或者非常消耗资源的操作的时候,防抖可以强制在一段连续的时间内只执行一次。
|
在一定的时间间隔内只执行一次,如果重新触发则重新计算时间间隔。常见的场景如,远程搜索输入框、浏览器resize、scroll等,主要为了节约服务器性能。 |
防抖函数为了防止函数多次调用 const debounce = function (func,wait = 50) { |
防抖函数常用来进行处理某些频繁触发的请求事件,如input搜索事件,如果用户每输入一个字都发送一次请求那么则会非常耗费性能,所以用防抖函数进行限制,在一定时间内触发的事件只有到了指定的时间才发送一次请求。 |
函数防抖
|
防抖用于频繁操作的情况,比如输入关键字匹配下拉列表,由于输入是连续的因此为了提高性能,在一定时间内输入则采用防抖延迟请求时间 |
防抖体会最深的,应该是下拉框的远程模糊搜索,不做防抖的话,每次用户输入变化,都立即请求服务器,对服务器负担太大。 |
防抖函数的作用是限制用户的频繁操作,影响网页的性能,防抖函数的原理是如果用户频繁操作事件处理函数就不会执行,只有当进行了最后一次操作,并且时间大于设定的时间才会执行;防抖函数的应用十分广泛:比如:1.只有在用户最后一次改变页面尺寸时才做一些操作,2:当用户在搜索框停止输入后发起Ajax请求; function debounce(fn, wait, immediate = false) {
let timer = null
return function(...arg){
if(immediate) {
fn.apply(this,arg)
immetiate = false
}
timer ? clearTimout(timer) : ""
timer = setTimeout(()=>{
fn.apply(this.arg)
},wait)
}
} |
window对象的resize,scroll事件。 |
1.防抖函数作用和应用场景:
} |
防抖函数(debounce):
|
在日常工作中,有三种场景我使用了防抖 什么是防抖
防抖的两种状态立即执行和非立即执行
立即执行
|
防抖意思懂,函数吧,就写不来了,看了别人写的,稍微懂了点 |
函数防抖
} |
防抖简单来说就是一段时间内只触发一次,跟节流很像(隔一段时间执行一次) |
关于 debounce 和 throttling 的区别,推荐一篇文章吧 https://css-tricks.com/debouncing-throttling-explained-examples/ |
谢谢给大家推荐好文,但是也别忘了好好阅读一下哈~ |
今日又比昨天进步了,这一点就已经超级赞了~ |
函数防抖:任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。 应用场景:
// 每次输入都发生请求
$('input.user-name').on('input', function () {
$.ajax({
url: `https://just.com/check`,
method: 'post',
data: {
username: $(this).val(),
},
success(data) {
if (data.isRegistered) {
$('.tips').text('该用户名已被注册!');
} else {
$('.tips').text('恭喜!该用户名还未被注册!');
}
},
error(error) {
console.log(error);
},
});
}); // 添加防抖函数
function debounce(fn, interval = 300) {
let timeout = null;
return function () {
clearTimeout(timeout);
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, interval);
};
}
$('input.user-name').on('input', debounce(function () {
$.ajax({
url: `https://just.com/check`,
method: 'post',
data: {
username: $(this).val(),
},
success(data) {
if (data.isRegistered) {
$('.tips').text('该用户名已被注册!');
} else {
$('.tips').text('恭喜!该用户名还未被注册!');
}
},
error(error) {
console.log(error);
},
});
})); 今日答题完成,感谢小姐姐带我们成长 |
/**
* @param fn {Function} 实际要执行的函数
* @param interval {Number} 延迟时间,默认 300 毫秒
*
* @return {Function}
*/
function debounce(fn, interval = 300) {
let timer = null;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
fn.applay(this, arguments);
}, interval);
}
} |
防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
节流:规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
|
防抖函数作用出现的原因在某段连续时间内,多次触发请求 为造成资源浪费,为了解决客户端的性能问题 出现了防抖 什么是防抖在某段连续时间内在事件触发后只执行一次 作用解决高频繁问题,既能节省浏览器CPU资源,又能让页面浏览更加顺畅,不会因为js的执行而发生卡顿 实现fangdou(fn, delay) { |
防抖函数的作用是防止频繁触发某个事件 原理:利用定时器,当事件触发后一段该事件内再次触发,则重新开始计时,等到计时器结束之后,才做该事件的响应 应用场景:最常见的就是搜索框了,当我们一直键入的时候,键盘事件一直在触发,但是只有我们不键入一会,搜索框才会带着关键词去请求响应的数据回来。防抖减少网络请求等事件的次数。 写一个防抖: function debounce(fn,interval) {
let timer
return function(...args) {
if (timer) return false
timer = setTimeout(() => {
fn(...args)
clearTimeout(timer)
}, interval)
}
}
const fn = debounce((...args) => console.log(args),1000)
fn(1,2)
fn(2,3)
fn(4,5)
fn(4,2)
// 只输出[1,2] fn函数频繁调用,却只输出一次! |
今天这个题看一些博客,还是有点不解,可能是在平时没有用到过的原因,这个防抖说的大概意思就是,函数执行完一次再去触发执行第二次,如果是这样的话,设置一个开关是否可行,还有设置一个倒计时,函数触发后倒计多少秒后在执行; var timer = null |
防抖防抖( function debounce(fn,delay){
let timer = null;
return function(){
let ctx = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(()=>{
fn.apply(ctx,args);
},delay);
}
} 防抖函数的应用
说了防抖,还有一个跟防抖比较类似的概念 :节流( 节流节流( function throttle(fn,delay){
let timer = null;
return function(){
let ctx = this;
let args = arguments;
if(timer === null){
timer = setTimeout(()=>{
fn.apply(ctx,args);
timer = null;
},delay)
}
}
} 节流函数的应用
区别虽然防抖和节流很像,他们都是在持续触发事件时,做一些相应的操作来实现节省资源,但是还是有一些不同
|
在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove 等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数。 防抖函数分为非立即执行版和立即执行版。 非立即执行版
立即执行版
|
防抖,又称函数节流,背后基本思想是指:某些代码不可以没有间断的情况连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的是只有在执行函数请求停止了一段时间之后才执行。
节流在resize事件中是最常用的,如下案例,设置一个div的高度适中和宽度保持一致
|
等情况,防止函数过于频繁的不必要的调用。 function debounce(func, wait, immediate) {
} |
防抖函数的作用防抖函数的作用就是控制函数在一定时间内的执行次数。防抖意味着N秒内函数只会被执行一次,如果N秒内再次被触发,则重新计算延迟时间。 举例说明: 小思最近在减肥,但是她非常贪吃。为此,与其男朋友约定好,如果10天不吃零食,就可以购买一个包(不要问为什么是包,因为包治百病)。但是如果中间吃了一次零食,那么就要重新计算时间,直到小思坚持10天没有吃零食,才能购买一个包。所以,管不住醉的小思,一次没有机会买包(悲伤的故事)... 不管吃没吃零食,每10天买一个包,是节流。而我们这是啥,这是防抖。如何控制女朋友的消费,各位攻城狮们,get到了吗?防抖可比节流有效多了! 防抖应用场景
防抖函数实现function debounce(func, wait, immediate=true) {
let timeout, context, args;
// 延迟执行函数
const later = () => setTimeout(() => {
// 延迟函数执行完毕,清空定时器
timeout = null
// 延迟执行的情况下,函数会在延迟函数中执行
// 使用到之前缓存的参数和上下文
if (!immediate) {
func.apply(context, args);
context = args = null;
}
}, wait);
let debounced = function (...params) {
if (!timeout) {
timeout = later();
if (immediate) {
//立即执行
func.apply(this, params);
} else {
//闭包
context = this;
args = params;
}
} else {
clearTimeout(timeout);
timeout = later();
}
}
debounced.cancel = function () {
clearTimeout(timeout);
timeout = null;
};
return debounced;
}; 偷个懒,睡睡睡觉去了~~~ |
函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。 应用场景: 监听滚动事件,input 模糊搜索,图片的拖拽等
@1353619565 写的非常好,学习了,多谢,重温一下
|
防抖的原理就是:你尽管触发事件,我反正在事件出发n秒之后才会执行,如果在一个事件触发之后的n内又触发了该事件,那就以新的事件的时间为准,n秒之后再执行。 //立即执行
function debounce(func, wait, immediate){
var timer;
return function(){
const _this = this;
const args = arguments;
if(timer) clearInterval(timer);
if(immediate){
var callNow = !timer;
timer = setTimeout(function(){
timer = null;
}, wait);
if(callNow) func.apply(_this, args);
}else{
timer = setTimeout(function(){
func.apply(_this, args);
}, wait);
}
}
} |
防抖函数理解: |
函数防抖
//函数防抖,输入框应用
function debounce(fun, delay) {
return function (args) {
let that = this
let _args = args
clearTimeout(fun.id)
fun.id = setTimeout(function () {
fun.call(that, _args)
}, delay)
}
}
let inputb = document.getElementById('debounce')
let debounceAjax = debounce(ajax, 500)
inputb.addEventListener('keyup', function (e) {
debounceAjax(e.target.value)
}) 防抖应用场景
|
防抖和节流的概念 防抖(debounce) 节流(throttle)
应用场景
节流: |
理解函数防抖函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次。 简单实现funtion debounce(func,wait) {
var timeout;
return function() {
var context = this;
clearTimeout(timeout);
timeout = setTimeout(function() {
func.apply(context);
},wait)
}
} |
防抖函数 |
问题1: 如果实现了dom拖拽功能,但是在绑定拖拽事件的时候发现每当元素稍微移动一点便触发了大量的回调函数,导致浏览器直接卡死,这个时候怎么办? 问题2:如果给一个按钮绑定了表单提交的post事件,但是用户有些时候在网络情况极差的情况下多次点击按钮造成表单重复提交,如何防止多次提交的发生? 1、定义函数防抖(debounce)
函数节流(throttle)
2、作用解决高频繁问题,既能节省浏览器CPU资源,又能让页面浏览更加顺畅,不会因为js的执行而发生卡顿 3、二者的区别
4、使用场景防抖
节流
5、实现
防抖 js代码:
运行效果: 节流 js代码:
如果错误请指出,谢谢!>_< 参考链接:https://juejin.im/post/5b8de829f265da43623c4261#heading-2 |
防抖是什么?防抖是什么?防抖就是防止抖动,例如小朋友喜欢多动,停不下来,然后做家长的打一顿,让小朋友安静下来,这种行为就叫做防抖。 (~o ̄3 ̄)~ 抖个机灵,哈哈哈~ 抖动是一个很常见的控制函数在一定时间内执行多少次的技巧,其实就是确定了函数执行的最小间隔,如果还在这个间隔内触发函数,则重新计算。 举个栗子~ 你家有七个儿子,大儿子叫大娃,二儿子叫二娃,三儿子叫三娃,四儿子叫四娃,五儿子叫五娃,六儿子叫六娃,七儿子叫七娃。由于七个孩子还小,他们的衣服你只能用手洗,一洗洗七套,一次要一个小时。如果洗到一半,你的七个孩子给你过来捣乱把衣服弄脏,那么你又得花一个小时去洗,不捣乱,那么你一个小时之后你的孩子衣服就又脏了,又可以再花一个小时来洗衣服了。 具体实现鱼头注:以下代码来自优秀的JS库 // 判断是不是个对象
function isObject(value) {
const type = typeof value
return value != null && (type == 'object' || type == 'function')
}
/*
* 创建一个 debounced 函数,延迟调用 func 直到 wait 之后
* cancel 方法用于取消 debounced
* flush 方法用于立即调用
*/
function debounce(func, wait, options) {
let lastArgs,
lastThis,
maxWait,
result,
timerId,
lastCallTime
let lastInvokeTime = 0
let leading = false
let maxing = false
let trailing = true
// 绕过 requestAnimationFrame ,显式地设置 wait = 0
const useRAF = (!wait && wait !== 0 && typeof root.requestAnimationFrame === 'function')
if (typeof func !== 'function') {
throw new TypeError('Expected a function')
}
wait = +wait || 0
if (isObject(options)) {
leading = !!options.leading
maxing = 'maxWait' in options
maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait
trailing = 'trailing' in options ? !!options.trailing : trailing
}
function invokeFunc(time) {
const args = lastArgs
const thisArg = lastThis
lastArgs = lastThis = undefined
lastInvokeTime = time
result = func.apply(thisArg, args)
return result
}
function startTimer(pendingFunc, wait) {
if (useRAF) {
root.cancelAnimationFrame(timerId);
return root.requestAnimationFrame(pendingFunc)
}
return setTimeout(pendingFunc, wait)
}
function cancelTimer(id) {
if (useRAF) {
return root.cancelAnimationFrame(id)
}
clearTimeout(id)
}
function leadingEdge(time) {
// 重置任何 最大等待时间的计时器
lastInvokeTime = time
// 启动计时器
timerId = startTimer(timerExpired, wait)
// 返回调用结果
return leading ? invokeFunc(time) : result
}
function remainingWait(time) {
const timeSinceLastCall = time - lastCallTime
const timeSinceLastInvoke = time - lastInvokeTime
const timeWaiting = wait - timeSinceLastCall
return maxing
? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting
}
function shouldInvoke(time) {
const timeSinceLastCall = time - lastCallTime
const timeSinceLastInvoke = time - lastInvokeTime
// 判断是否应该调用函数
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait))
}
function timerExpired() {
const time = Date.now()
if (shouldInvoke(time)) {
return trailingEdge(time)
}
// 重置定时器
timerId = startTimer(timerExpired, remainingWait(time))
}
function trailingEdge(time) {
timerId = undefined
// 如果我有最后一个参数,就意味着函数需要调用
// 至少执行一次防抖
if (trailing && lastArgs) {
return invokeFunc(time)
}
lastArgs = lastThis = undefined
return result
}
function cancel() {
if (timerId !== undefined) {
cancelTimer(timerId)
}
lastInvokeTime = 0
lastArgs = lastCallTime = lastThis = timerId = undefined
}
function flush() {
return timerId === undefined ? result : trailingEdge(Date.now())
}
function pending() {
return timerId !== undefined
}
function debounced(...args) {
const time = Date.now()
const isInvoking = shouldInvoke(time)
lastArgs = args
lastThis = this
lastCallTime = time
if (isInvoking) {
if (timerId === undefined) {
return leadingEdge(lastCallTime)
}
if (maxing) {
// 处理循环调用
timerId = startTimer(timerExpired, wait)
return invokeFunc(lastCallTime)
}
}
if (timerId === undefined) {
timerId = startTimer(timerExpired, wait)
}
return result
}
debounced.cancel = cancel
debounced.flush = flush
debounced.pending = pending
return debounced
} 使用方法如下: var 打印一些东西啦 = function (event) {
console.log(event);
};
document.querySelector('html').addEventListener('click', debounce(打印一些东西啦, 1000)); 适用场景以下就举几个我们日常开发中可能会用上 debounce 的栗子:
|
防抖主要用在滚动条事件中,比如监听滚动条事件,为避免一秒内多次触发,利用防抖就可以做到在固定时间内不会多次执行 防抖的核心方法就是利用定时器
|
先假设一个场景:通常用户注册的时候,需要填写用户名,在用户输入用户名的过程中,我们可以主动发请求到后端去验证当前的用户名是否已经被注册。
如果用户想输入的用户名是 所以,本质上,我们要解决的问题就是,预测用户是否已经输入完成。我们可以认为,用户每停顿800毫秒以上的实际,默认已经完成,然后再去验证。
只要我们认为用户还在规定的时间间隔内触发事件,那么就会一直等待下去,这个就叫做 简单来说, |
防抖的原理就是设定定时器,例如scroll事件连续触发,并不会每一次触发都会调用处理方法,而是等某一次触发停止了一段时间(定时器设定的时间)后,进行处理方法的调用。如果在设定的时间还没有到,就再次触发,那么清空之前的定时器,重新计时,直到scroll事件触发停止了一段时间(定时器设定的时间),执行处理方法。
|
function debounce (fn, delay, immediate) {
let timeout = null
return function () {
clearTimeout(timeout)
let context = this
let args = arguments
if (!timeout && immediate) {
fn.apply(context, args)
}
timeout = setTimeout(() => {
if (!immediate) {
fn.apply(context, args)
} else {
immediate = null
}
}, delay)
}
} |
重新回答一次 |
什么是防抖当持续触发事件时,一定范围时间内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发事件,就重新开始延时 举例说明:当你乘电梯时,按下关电梯按钮,现在开始计时,如果5s内没有人点击开电梯按钮,你就会正常的乘着电梯上楼,如果5s内有人点击开电梯按钮,那么关门事件会重新开始延时5s再触发 什么是节流当持续触发事件时,保证一定时间段内只调用一次事件处理函数。 举例说明:身为一个妹子,特别喜欢买化妆品。为了控制自己,节约钱,规定自己一个月买一次化妆品。 作用处理高频事件,避免函数频繁调用,优化性能,减少浏览器或者服务器的压力。 防抖函数的应用场景
节流函数的应用场景
防抖函数的实现
节流函数的实现
参考资料 |
函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数 function debounce(func, wait, immediate=true) { |
防抖函数的作用函数防抖是指对于高频事件,在规定时间内,如果事件没有被再次触发则执行回调函数,如果事件被再次触发,则重新开始计时。 防抖函数的应用场景1、按钮提交 防抖函数的实现function debounce(fn, delay) {
var timer = null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
} |
No description provided.
The text was updated successfully, but these errors were encountered: