1.防抖:
防抖是指在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。(就是在触发某个事件后,在下一次触发之前,中间的间隔时间如果超过设置的时间才会发送请求,一直触发就不会发送请求)
前面的所有的触发都被取消,最后一次执行在规定的时间之后才会触发,也就是说连续快速的触发 只会执行一次。通过setTimeout的方式限制函数的执行次数,在一定的时间间隔内,将多次触发变成一次触发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="submit" id="input">
</body>
</html>
<script>
let btn = document.getElementById('input')
// btn.addEventListener('click',submit,false)
btn.addEventListener('click',debounce(submit),false)
function debounce(func,delay,immediate) {
let timer = null
/*
* 存在两个问题
* 1.当前的事件对象如何获取
* 2.this如何处理*/
//debounce要返回一个函数 点击btn 由window调用该函数
//返回的函数就是点击按钮后window调用的函数 会传递一个事件参数,但是我们不能直接传个e 因为我们目前不知道传参的个数是多少
//当不知道传入参数的个数时 是不能用形参来获取当前的参数列表
//这里我们使用arguments
return function() {
//这里的this是指向input
console.log(this)
console.log(arguments[0])
//当用户多次点击时,定时器就会存在多个 下面if判断 只要存在定时器就会清除重新生成
//多次点击只会执行一次 就实现了防抖的效果
if(timer){
clearTimeout(timer)
}
//问题:当我们第一次点击的时候 也执行了延时处理
//解决
if(immediate){
//判断是不是第一次 timer = null时
/*
* 注:一般涉及到null判断时 会把null写成布尔值
* 原因:undefined == null 可能还会造成错误判断*/
let firstClick = !timer /*timer为null !timer为布尔值true*/
if(firstClick) {
func.apply(this, arguments)
}
timer = setTimeout(() =>{
timer = null
},delay)
}else {
//限制func的执行
timer = setTimeout(()=> {
//每一个实参列表对应自己内部的函数 这里的实参是定时器函数的 与外层函数的不是同一个
/*
* 改变实参指向两种方法
* 1.用赋值方式
* 2.用箭头函数 将内部的arguments指向改成外部函数的arguments指向*/
console.log(arguments[0])
//这里的this拿的是箭头函数外部的this
func.apply(this,arguments)
}, delay)
}
}
}
function submit(e){
//如果是没有包装之前的函数
//btn.addEventListener('click',submit,false)
//这里的this指向input
console.log(this)
//此时的事件参数e为MouseEvent
console.log(e)
}
function debounce(fn,delay,immediate) {
return function () {
let timer = null
let firstClick = !timer
if(timer){
clearTimeout(timer)
}
//判断是不是第一次点击
if(firstClick){
fn.apply(this,arguments)
}
setTimeout(()=>{
timer = null
},delay)
}
}
</script>
2.节流:
在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="submit" id="input">
</body>
</html>
<script>
let btn = document.getElementById('input')
// btn.addEventListener('click',submit,false)
btn.addEventListener('click',debounce(submit),false)
function submit(e){
//如果是没有包装之前的函数
//btn.addEventListener('click',submit,false)
//这里的this指向input
console.log(this)
//此时的事件参数e为MouseEvent
console.log(e)
}
function throttle(fun,delay) {
//第一次点击的时间
let begin =0
return function () {
//获取当前时间戳
let cur = new Date().getTime()
//当前点击与上一次点击的时间差
if(cur - begin > delay){
fun.apply(this.arguments)
begin = cur
}
}
}
</script>