防抖函数
实现的目的
当持续触发事件,在设定的时间内没有再触发该事件,事件处理函数会执行一次;如果未到设定的时间,又一次触发了事件,会重新开始计时。
实际应用
-
搜索:输入结束后n毫秒(或秒)才进行搜索请求,n秒内又输入内容,重新计时;
-
浏览器窗口执行resize,重新渲染页面
代码:
//第一种 非立即执行版
function debounce(func, wait) {
let timeout;
return function () {
const context = this;
const args = [...arguments];
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
//第二种 立即执行版
function debounce(func, wait) {
let timeout;
return function () {
const context = this;
const args = [...arguments];
if (timeout) clearTimeout(timeout);
const callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
}
function inputFun(value){
console.log(`你输出的结果是${value}`)
}
let input = document.getElementById('test');
let debounceInput = debounce(inputFun,500);
input.addEventListener('keyup',function(e){
debounceInput(e.target.value)
})
节流函数
实现的目的
当持续触发事件的时候,设定的时间内,只调用一次事件处理函数。
实际应用
- Form表单的提交 鼠标不断点击触发,设定事件内只有一次生效。
代码实现
//第一种 用定时器的方式实现
function throttle(func, wait) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
//第二种 时间戳版:
function throttle(func, wait) {
var previous = 0;
return function () {
let now = Date.now();
let context = this;
let args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
function handle(){
console.log(Math.random())
}
document.getElementById('btn').onclick = throttle(handle,1000)