目录
防抖
搜索框带来的问题
实现的思路
案例
封装防抖函数
节流
滚动条加载带来的问题
实现的思路
案例
封装节流函数
防抖
搜索框带来的问题
需求:根据输入框内容来请求数据
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><input id="searchTxt" type="search" placeholder="请输入关键字检索"><script>document.querySelector("#searchTxt").oninput = function(){console.log('发送请求,当前输入框值:',this.value)}</script>
</body>
</html>
上面的代码会带来一个问题:用户每输入一个关键字都会触发
现在是要求是用户停下来不输入的时候再触发一次,这个时候就需要用到防抖函数了
实现的思路
-
事件函数执行,先创建个定时器
-
把逻辑代码放到定时器中
-
当函数再次触发,清除定时器
-
创建一个新定时器即可
案例
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><input id="searchTxt" type="search" placeholder="请输入关键字检索"><script>let t = nulldocument.querySelector("#searchTxt").oninput = function(){clearTimeout(t) //有定时器则清除t = setTimeout(() => {console.log('发送请求,当前输入框值:',this.value)}, 1000);}</script></body></html>
封装防抖函数
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><input id="searchTxt" type="search" placeholder="请输入关键字检索"><script>document.querySelector("#searchTxt").oninput = debounce(function(){console.log('发送请求,当前输入框值:',this.value)})//封装一个公共的防抖函数function debounce(fn){//将函数逻辑放入fn中let t = null //此处利用闭包保存定时器return function(){clearTimeout(t) //有定时器则清除t = setTimeout(() => {//箭头函数指向外面函数的this,而外面函数由input触发fn.call(this) //利用call改变fn的this,否则fn的this为undefined}, 1000);}}</script></body></html>
节流
滚动条加载带来的问题
需求:页面滚动时,加载数据列表
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.box{height: 1000px;}</style></head><body><div class="box"></div><script>document.onscroll = function(){console.log('发送ajax,请求下一页数据')}</script></body></html>
上面的代码会带来一个问题:用户轻轻下拉滚动条,onscroll中的逻辑会触发很多次
现在是要求是降低触发事件的频率,这个时候就需要用到节流函数了。
实现的思路
-
事件函数执行,先判断是否有定时器,有则直接return
-
把逻辑代码放到定时器中
-
定时器执行后,置空定时器变量
-
事件函数执行时,再创建一个新的定时器
案例
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.box{height: 1000px;}</style></head><body><div class="box"></div><script>let t = nulldocument.onscroll = function(){if(null != t) return //关键点1:有定时器则returnt = setTimeout(() => {//关键点2:逻辑代码放到定时器中console.log('发送ajax,请求下一页数据')t = null //关键点3:定时器执行完毕,置空定时器变量}, 500);}</script></body></html>
封装节流函数
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.box{height: 1000px;}</style>
</head>
<body><div class="box"></div><script>document.onscroll = throttle(function () {console.log('发送ajax,请求下一页数据',this)})//封装一个节流函数function throttle(fn) {return function(){ //真正的事件处理函数(this:事件源)//这里用的是fn.t变量的形式来保存定时器变量if(null != fn.t) return fn.t = setTimeout(() => { fn.call(this)
//确保上面的函数中this关键字是事件源(如果用fu()调用,上面this就变成了window)fn.t = null
//置空,让事件再次触发的时候,重新创建一个定时器}, 500);}}</script>
</body>
</html>