都是为了解决高频触发事件,减少请求
防抖: 当频繁触发事件,一段时间内没有再次触发这个事件,它就会执行定时器里面的代码, 例如:回城
节流:当频繁的触发某个事件,它会降低执行的次数, 例如游戏中的 技能cd冷却时间
防抖常用于 input 输入框事件
第一张图片就输入你好,这两个字,它就执行了六次,那若输入很长的句子,就要执行很多次
如果每一次输入都和后台进行数据交互,请求数据,这就有点消耗性能,因此就有了防抖这个功能
第一张效果图
let inp = document.querySelector('input')
inp.oninput = function () {
console.log(this.value)
}
第二张效果图 第一种利用定时器实现防抖
let inp = document.querySelector('input')
let t = null //全局环境下定义一个计时器的t
inp.oninput = function () {
if (t !== null) {
clearTimeout(t) 之前触发了就使用clear...清空定时器
}
t = setTimeout(() => {
console.log(this.value)
}, 500);
}
防抖:用户触发时间过于频繁,只要最后一次事件的操作
上面那个方法 分为 全局变量 / 防抖代码 / 自己要实现的代码
多了一个全局变量 ,在里面添加逻辑的话, 以后它不太便于维护 因此可以闭包封装防抖方法解决
第二种 使用闭包 封装防抖的方法实现防抖
- // 防抖
- let inp = document.querySelector('input')
- //不太便于维护 使用闭包封装防抖方法解决
- inp.oninput = debounce(function(){
- console.log(this.value) //指向window
- },500)
-
- function debounce(fn,del) {
- let t = null
- return function () {
- if (t !== null) {
- clearTimeout(t)
- }
- t= setTimeout(() => {
- fn.call(this)
- }, del);
-
- }
- }
没有使用 fn.call(this) 会报undefined ,因为 第一个function 它的this指向window
因为 input调用的debounce函数 debounce函数 里的定时器是箭头函数 箭头函数里的this指向input
// 防抖
let inp = document.querySelector('input')
//不太便于维护 使用闭包封装防抖方法解决
inp.oninput = debounce(function(){
console.log(this.value) //指向window
},500)
// fn形参上面的function del:延迟时间
function debounce(fn,del) {
let t = null //内部函数使用 t 也就是外部函数变量 因为闭包这个函数也不会被销毁
return function () {
if (t !== null) {
clearTimeout(t)
}
t= setTimeout(() => {
console.log(this,'this') //这里的this指向input
fn()
}, del);
}
}
箭头函数this是所处函数return / function 的this,而return /function 是 debounce 函数的返回值所以this是input 而fn函数是参数函数,没人调用,this自然是window
body{height: 2000px;}
// 节流 滚动条事件 大家可以试试
window.onscroll = function() {
console.log('123');
}
打印结果 自己试了就知道
// 节流:控制执行次数
let t = true
window.onscroll = function() {
if (t) {
setTimeout(() => {
console.log('123')
}, 500);
}
t = false
}
上面的代码 只执行一次 ,因为它开始是true 直到false就不执行了
// 节流:控制执行次数
// 节流的作用:控制高频时间执行次数
let t = true
window.onscroll = function() {
if (t) {
setTimeout(() => {
console.log('123')
t = true
}, 500);
}
t = false
}
也可以使用闭包的方法
// 节流:控制执行次数
// 节流的作用:控制高频时间执行次数
window.onscroll = flag(function() {
console.log('123');
},500)
function flag(fn,timers){
let t = true
return function(){
if (t) {
setTimeout(() => {
fn()
t = true
}, timers);
}
t = false
}
}