防抖debounce
+.监听一个输入框,文字变化后触发change事件
+.如果没有用防抖,直接用keyup事件,则会频发change事件,影响性能
+.但是采用防抖:用户输入结束或者暂停时,彩绘触发change事件
debounce 一段时间内连续的函数调用,只允许其函数执行一次。原理是,维护一个定时器,只有定时器结束才可以继续触发事件。
未封装代码代码(用于巩固理解):
let timer = null
let oInput = document.getElementById('input')
oInput.addEventListener('keyup', function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(function(){
console.log(oInput.value)
}, 500)
})
封装好的代码:
// setTimeout是过了一段事件后触发函数体
// 防抖就是说,比如当在文本框内输入内容,如果在时间没有到之前继续输入文字内容,那么最后的时间将是最后一个文字输入时间一直到结束
function debounce(fn, delay=500){
// 给闭包使用
let timer = null
return function(){
if(timer){
clearTimeout(timer)
}
// 采用箭头函数,如果采用ES5的写法,则this会指向Window
timer = setTimeout(() => {
// 指向fn这个函数,最好能这么写,比如传了event上面那个就会报错
fn.apply(this, arguments)
}, delay)
}
}
代码测试:(在一段时间(600ms)内连续触发debounce函数,但是debounce函数只会执行一次,当用户不在输入文字时,并且在输入最后一次文字等待600ms结束才会触发funtion(){console.log(oInput.value}),并且取消定时器
let oInput = document.getElementById('input')
// 要知道传进去什么,然后返回什么
oInput.addEventListener('keyup', debounce(function(){
console.log(oInput.value)
}, 600))
节流throttle
+.拖拽一个元素时,要随时拿到该元素被拖拽的位置
+.直接用drag事件,则会频繁触发,很容用导致卡顿
+.但是使用节流,无论拖拽速度多块,都会每隔100ms触发一次
throttle:一段时间内的函数调用,保证事件一定会被执行一次。节流可以保证在一段时间内函数必定会触发一次。
未封装代码(用于巩固):
const oDiv1 = document.getElementById('div1')
let timer = null
oDiv1.addEventListener('drag', function(e){
if(timer) {
return false//事件停止执行并跳出函数
}
// timer也可以是执行的次数
timer = setTimeout(function () {
// console.log(timer)
console.log(e.offsetX, e.offsetY)
// 因为timer为null,这个定时器才能持续运行
timer = null// 因为是null,所以继续执行这个计时器
}, 500)// 500秒后执行函数体,此时timer有值了,如果此时停止滑动,则执行判断语句
})
封装后的代码:
// 节流就是说,在触发时候是没有的,只有规定的时间内才触发事件,然后想要触发时候触再进入到这个函数体
function throttle(fn, delay=100){
let timer = null
return function(){
// let _this = this
// let arg = arguments
if(timer){
return false
}
timer = setTimeout(() => {//要采用箭头函数,采用ES5写法则this会指向window
fn.apply(this, arguments)
timer = null
}, delay)
}
}
// test
const oDiv1 = document.getElementById('div1')
oDiv1.addEventListener('drag', throttle(function (e) {
console.log(e.offsetX, e.offsetY)
},1000))
测试
当在拖拽的时候,第一个100ms内是不会执行的的,到了100ms时候,执行上面箭头函数体一次,然后因为函数体的timer=null跳出return的函数体,最后重复下一个100ms的动作。
const oDiv1 = document.getElementById('div1')
oDiv1.addEventListener('drag', throttle(function (e) {
console.log(e.offsetX, e.offsetY)
}, 100))
防抖的典型案例就是输入搜索:输入结束后n秒才进行搜索请求,n秒内又输入的内容,就重新计时。
节流的典型案例就是鼠标不断点击触发,规定在n秒内多次点击只有一次生效。