Ps: 예를 들어, 사용자는 검색 상자에서 변경
을 사용합니다. code> 이벤트 입력 시 검색을 호출하려면 사용자가 입력할 때마다 검색하면 서버 리소스가 얼마나 소모되나요? change
事件去调用搜索,如果用户每一次输入都去搜索的话,那得消耗多大的服务器资源,即使你的服务器资源很强大,也不带这么玩的。
其中一种解决方案就是每次用户停止输入后,延迟超过500ms
时,才去搜索此时的String
,这就是防抖。
原理:将若干个函数调用合成为一次,并在给定时间过去之后仅被调用一次。
代码实现:
function debounce(fn, delay) { // 维护一个 timer,用来记录当前执行函数状态 let timer = null; return function() { // 通过 ‘this’ 和 ‘arguments’ 获取函数的作用域和变量 let context = this; let args = arguments; // 清理掉正在执行的函数,并重新执行 clearTimeout(timer); timer = setTimeout(function() { fn.apply(context, args); }, delay); } } let flag = 0; // 记录当前函数调用次数 // 当用户滚动时被调用的函数 function foo() { flag++; console.log('Number of calls: %d', flag); } // 在 debounce 中包装我们的函数,过 2 秒触发一次 document.body.addEventListener('scroll', debounce(foo, 2000));
debounce
函数封装后,返回内部函数每一次事件被触发,都会清除当前的
timer
然后重新设置超时并调用。这会导致每一次高频事件都会取消前一次的超时调用,导致事件处理程序不能被触发只有当高频事件停止,最后一次事件触发的超时调用才能在
delay
时间后执行
另一种解决方案比 防抖 要宽松些,这时我们不想用户一味的输入,而是给用户一些搜索提示,所以在当中限制每过500ms
就查询一次此时的String
,这就是节流。
原理:节流函数不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。
代码实现有两种,一种是时间戳,另一种是定时器
1)时间戳实现:
function throttle(func, delay){ let prev = Date.now(); return function(){ const context = this; const args = arguments; const now = Date.now(); if(now - prev >= delay){ func.apply(context, args); prev = Date.now(); } } }
当高频事件触发时,第一次应该会立即执行(给事件绑定函数与真正触发事件的间隔如果大于delay
的话),而后再怎么频繁触发事件,也都是会每delay
秒才执行一次。而当最后一次事件触发完毕后,事件也不会再被执行了。
2)定时器实现:
当触发事件的时候,我们设置一个定时器,再触发事件的时候,如果定时器存在,就不执行;直到delay
秒后,定时器执行执行函数,清空定时器,这样就可以设置下个定时器。
fucntion throttle(func, delay){ let timer = null; return funtion(){ let context = this; let args = arguments; if(!timer){ timer = setTimeout(function(){ func.apply(context, args); timer = null; }, delay); } } }
当第一次触发事件时,肯定不会立即执行函数,而是在delay
秒后才执行。
之后连续不断触发事件,也会每delay
秒执行一次。
当最后一次停止触发后,由于定时器的delay
延迟,可能还会执行一次函数。
3)综合使用时间戳与定时器,完成一个事件触发时立即执行,触发完毕还能执行一次的节流函数
function throttle(func, delay){ let timer = null; let startTime = Date.now(); return function(){ let curTime = Date.now(); let remaining = delay - (curTime - startTime); const context = this; const args = arguments; clearTimeout(timer); if(remaining <= 0){ func.apply(context,args); startTime = Date.now(); }else{ timer = setTimeout(func, remaining); } } }
需要在每个해결책 중 하나는 사용자가 입력을 멈추고 지연이delay
时间中一定会执行一次函数,因此在节流函数内部使用开始时间、当前时间与delay
来计算remaining
,当remaining <= 0
时表示该执行函数了,如果还没到时间的话就设定在remaining
时间后再触发。当然在remaining
这段时间中如果又一次发生事件,那么会取消当前的计时器,并重新计算一个remaining
1. 흔들림 방지 - 디바운스
500ms
를 초과할 때마다 이를 검색하는 것입니다. code>String, 이것은 흔들림 방지 기능입니다.
#🎜🎜#
- # 🎜🎜#
디바운스
함수가 캡슐화된 후 내부 함수가 반환됩니다.이벤트가 트리거될 때마다 현재
타이머
will becleared>그런 다음 시간 제한을 재설정하고 호출하세요. 이렇게 하면 각 고주파 이벤트가 이전 시간 초과 호출을 취소하여 이벤트 핸들러가 트리거되지 않게 됩니다.- 고빈도 이벤트가 중지될 때만 마지막 이벤트 타임아웃 호출은
delay
시간Throttle - throttle
#🎜🎜# 후에만 실행될 수 있습니다. another 이 솔루션은 Anti-shake보다 더 완화되었습니다. 이때 사용자가 무작정 입력하는 것을 원하지 않지만 사용자에게 몇 가지 검색 프롬프트를 제공하므로마다 쿼리를 제한합니다. 500ms
String
현재 이는 조절 중입니다. #🎜🎜#rrreee
- #🎜🎜#Principle: 이벤트가 아무리 자주 발생하더라도 조절 기능은 실제 이벤트 처리 기능이 한 번만 실행되도록 보장합니다. 지정된 시간. #🎜🎜#
- #🎜🎜#두 가지 코드 구현이 있습니다. 하나는 타임스탬프이고 다른 하나는 타이머입니다.
1) 타임스탬프 구현: #🎜🎜#고빈도 이벤트가 트리거되면 처음으로 즉시 실행되어야 합니다(이벤트 바인딩 기능과 실제 트리거 이벤트 사이의 간격이지연
보다 큰 경우). 그런 다음 이벤트가 얼마나 자주 트리거되는지에 관계없이delay
초마다 한 번만 실행됩니다. 마지막 이벤트가 트리거되면 해당 이벤트는 더 이상 실행되지 않습니다. #🎜🎜##🎜🎜#2) 타이머 구현:
이벤트가 다시 트리거될 때 타이머가 존재하면까지 실행되지 않습니다. 지연
초 후 타이머는 실행 기능을 실행하고 다음 타이머를 설정할 수 있도록 타이머를 지웁니다. #🎜🎜#rrreee이벤트가 처음 발생하면 함수는 당연히 바로 실행되지 않고지연
초 후에 실행됩니다.
그 이후에는 이벤트가 지속적으로 트리거되며지연
초마다 실행됩니다.
마지막 정지가 실행된 후 타이머의지연
지연으로 인해 기능이 다시 실행될 수 있습니다. #🎜🎜##🎜🎜#3) 타임스탬프와 타이머의 결합, 이벤트가 트리거될 때 즉시 실행되는 제한 기능이며, 트리거 후에 한 번만 실행될 수 있습니다. #🎜🎜#rrreee가 포함되어야 합니다. 각delay
시간에 한 번씩 실행되므로 시작 시간, 현재 시간 및delay
는 조절 함수 내에서남은 시간
을 계산하는 데 사용됩니다.일 때 이면 함수를 실행할 시간임을 의미합니다. 해당 시간이 아직 도달하지 않은 경우 <code>남은
이후에 트리거하도록 설정합니다. 시간. 물론,남은 시간
기간 동안 다시 이벤트가 발생하면 현재 타이머는 취소되고남은 시간
을 다시 계산하여 현재 상태를 판단하게 됩니다. #🎜🎜##🎜🎜#관련 기사: #🎜🎜##🎜🎜##🎜🎜#자바스크립트 기능의 조절 및 흔들림 방지 디바운스에 대한 자세한 설명#🎜🎜##🎜🎜##🎜🎜##🎜🎜 # 자바스크립트 기능 조절 및 흔들림 방지에 대한 자세한 설명#🎜🎜##🎜🎜#
위 내용은 손떨림 방지의 JS 간단한 구현 - 디바운스 및 조절 - 조절의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!