JS防抖其实也是用来提升网页性能的一种技术写法
如果你想直接看源码的话直接划到最后面!(还是建议一步一步的操作来)
防抖就是指当用户触发某个操作时,如果在指定的时间内再次触发该操作,那么就清除前面触发的操作,直到用户操作之后并且在指定的时间内不再操作我们再处理用户的请求。
比如说:点击按钮执行搜索操作的时候,如果用户一秒内重复点击按钮,这个时候由于重复提交,页面就会变卡。
1.第一步:先把按钮的点击事件绑定上去。点击按钮控制台会数据 ‘11111’,这个时候重复点击按钮还是会重复调用按钮的点击事件。
html部分
<button type="button" id="btn">提 交</button>
js部分
//获取 按钮
let btn = document.querySelector('#btn');
// 给按钮添加事件监听 palyMoney方法
btn.addEventListener('click',palyMoney)
function palyMoney() {
console.log('11111')
}
2.第二步:开始设置防抖设置
js部分
//获取 按钮
let btn = document.querySelector('#btn');
// 提交方法
function palyMoney() {
console.log('11111')
}
// 防抖函数
function buttonClick(func){
func();
}
// 给按钮添加事件监听 buttonClick方法
btn.addEventListener('click',buttonClick(palyMoney))
这个时候打开页面的时候发现 直接就运行了 palyMoney() 这个方法,
这个就是防抖的第一个难点
这里就需要使用到闭包来处理。防止给按钮添加时间监听的时候 就调用了palyMoney方法。
js部分
//获取 按钮
let btn = document.querySelector('#btn');
// 提交方法
function palyMoney() {
console.log('11111')
}
// 防抖函数
function buttonClick(func){
// 使用闭包来防止 打开页面的时候就运行palyMoney 方法
return function(){
func();
}
}
// 给按钮添加事件监听 buttonClick方法
btn.addEventListener('click',buttonClick(palyMoney))
到这里刷新页面就不会执行这个方法了,只有我们点击时候才会执行这个方法。
现在我们就要给这个防抖函数添加延时器来实现防抖功能
//获取 按钮
let btn = document.querySelector('#btn');
// 提交方法
function palyMoney() {
console.log('11111')
}
//防抖函数
function buttonClick(func, time) {
//这里必须在 函数外部进行 声明 否则 每一次执行是互不干扰。
let timer
//注意这里不能使用箭头函数 否则会改变this的指向
return function() {
// 清除 timer 延时方法
clearTimeout(timer);
timer = setTimeout(() => {
func();
}, time)
}
}
// 给按钮添加事件监听 buttonClick方法 1000 为延时时间
btn.addEventListener('click', buttonClick(palyMoney, 1000))
这样就可以实现简单的防抖功能了,但是第二个难点就来了
//获取 按钮
let btn = document.querySelector('#btn');
// 提交方法
function palyMoney() {
console.log('11111')
console.log(this)
}
//防抖函数
function buttonClick(func, time) {
//这里必须在 函数外部进行 声明 否则 每一次执行是互不干扰。
let timer
//注意这里不能使用箭头函数 否则会改变this的指向
return function() {
// 清除 timer 延时方法
clearTimeout(timer);
timer = setTimeout(() => {
func();
}, time)
}
}
// 给按钮添加事件监听 buttonClick方法 1000 为延时时间
btn.addEventListener('click', buttonClick(palyMoney, 1000))
可以发现现在this的指向变成了 window
原来是指向的是 button本身的 但是现在变成了window
//获取 按钮
let btn = document.querySelector('#btn');
// 提交方法
function palyMoney() {
console.log('11111')
console.log(this)
}
// 防抖函数
function buttonClick(func, time) {
//这里必须在 函数外部进行 声明 否则 每一次执行是互不干扰。
let timer
//注意这里不能使用箭头函数 否则会改变this的指向
return function() {
// 清除 timer 延时方法
clearTimeout(timer);
timer = setTimeout(() => {
func();
}, time)
}
}
// 给按钮添加事件监听 buttonClick方法 1000 为延时时间
// btn.addEventListener('click', buttonClick(palyMoney, 1000))
// 对着实验!
btn.addEventListener('click', palyMoney)
解决方案
//获取 按钮
let btn = document.querySelector('#btn');
// 提交方法
function palyMoney(obj) {
console.log('11111')
console.log(this)
}
// 防抖函数
function buttonClick(func, time) {
//这里必须在 函数外部进行 声明 否则 每一次执行是互不干扰。
let timer
//注意这里不能使用箭头函数 否则会改变this的指向
return function() {
let _this = this;
// 清除 timer 延时方法
clearTimeout(timer);
timer = setTimeout(() => {
func.call(_this);
// palyMoney 方法需要带参数 可以将call 改成 apply
// func.call(_this,obj);
}, time)
}
}
// 给按钮添加事件监听 buttonClick方法 1000 为延时时间
btn.addEventListener('click', buttonClick(palyMoney, 1000))
// 对着实验!
// btn.addEventListener('click', palyMoney)
防抖就解决了:
最后,加上一点点样式,然后全部的代码部分。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<style>
div {
width: 400px;
height: 200px;
margin: 0 auto;
}
#btn {
width: 100px;
height: 40px;
line-height: 40px;
color: #fff;
background-color: #409eff;
border: 1px solid #409eff;
margin-top: 20px;
border-radius: 4px;
text-align: center;
white-space: nowrap;
cursor: pointer;
}
#btn:hover,
#btn:focus {
background: #66b1ff;
border-color: #66b1ff;
color: #fff;
outline: 0px;
}
#btn:active {
background: #3a8ee6;
border-color: #3a8ee6;
color: #fff;
}
</style>
</head>
<body>
<div>
<button type="button" id="btn">提 交</button>
</div>
<script type="text/javascript">
//获取 按钮
let btn = document.querySelector('#btn');
// 提交方法
function palyMoney() {
console.log('11111')
console.log(this)
}
// 防抖函数
function buttonClick(func, time) {
//这里必须在 函数外部进行 声明 否则 每一次执行是互不干扰。
let timer
//注意这里不能使用箭头函数 否则会改变this的指向
return function() {
let _this = this;
// 清除 timer 延时方法
clearTimeout(timer);
timer = setTimeout(() => {
func.call(_this);
}, time)
}
}
// 给按钮添加事件监听 buttonClick方法 1000 为延时时间
btn.addEventListener('click', buttonClick(palyMoney, 1000))
// 对着实验!
// btn.addEventListener('click', palyMoney)
</script>
</body>
</html>