函数防抖
用手风琴案例演示,做防抖优化前和优化后的区别
简易手风琴案例(防抖优化前 )
图片资源地址:https://github.com/jiang-zi/Optimize-anti-shake-/tree/master/images
<style>
ul {
list-style: none;
}
* {
margin: 0;
padding: 0;
}
div {
width: 1200px;
height: 400px;
margin: 50px auto;
border: 1px solid red;
overflow: hidden;
}
div li {
width: 240px;
height: 400px;
float: left;
transition: all 500ms;
}
div ul {
width: 1200px;
}
</style>
</head>
<body>
<div id="box">
<ul>
<li>
<a href="#">
<img src="./images/1.jpg" alt="" />
</a>
</li>
<li>
<a href="#">
<img src="./images/2.jpg" alt="" />
</a>
</li>
<li>
<a href="#">
<img src="./images/3.jpg" alt="" />
</a>
</li>
<li>
<a href="#">
<img src="./images/4.jpg" alt="" />
</a>
</li>
<li>
<a href="#">
<img src="./images/5.jpg" alt="" />
</a>
</li>
</ul>
</div>
</body>
<script>
//1.获取元素
let liList = document.querySelectorAll('#box li')
let box = document.querySelector('#box')
//2.注册事件
//2.1 鼠标移入
for (let i = 0; i < liList.length; i++) {
liList[i].onmouseenter = function () {
//3.排他思想修改宽度: 我自己800px,其他人100px
for (let j = 0; j < liList.length; j++) {
if (i === j) {
liList[j].style.width = '800px'
} else {
liList[j].style.width = '100px'
}
}
}
}
//2.2 鼠标移出父盒子
box.onmouseleave = function () {
//3.设置每一个li元素宽度240
for (let i = 0; i < liList.length; i++) {
liList[i].style.width = '240px'
}
}
</script>
结论 : 做函数防抖优化前,多次移入手风琴区域会出现抖动感。用户体验极其不好,还有内存资源得浪费。
解决方法 : 函数防抖
什么是函数防抖 : 间隔时间内 多次触发事件,以最后一次为准
函数防抖思路 :
- 声明一个变量存储定时器id
- 每一次触发事件的时候,先清除上一次的定时器,以本次为准
- 开启定时器,间隔时间之后再触发事件处理函数
此时只要用户在这个间隔时间之内触发了其他事件,那么上一次的定时器就会被清除
//防抖第一步:声明变量存储定时器id
let timeID = null
//2.注册事件
//2.1 鼠标移入
for (let i = 0; i < liList.length; i++) {
liList[i].onmouseenter = function () {
//防抖第二步: 每一次触发事件的时候,都要把上一次的定时器给移除。 以最后一次为准
clearTimeout(timeID)
//防抖第三步:每一次触发事件的时候,先不触发。开启定时器,间隔时间之后再触发
timeID = setTimeout(function () {
//3.排他思想修改宽度: 我自己800px,其他人100px
for (let j = 0; j < liList.length; j++) {
if (i === j) {
liList[j].style.width = '800px'
} else {
liList[j].style.width = '100px'
}
}
}, 300)
}
}
//2.2 鼠标移出父盒子
box.onmouseleave = function () {
//3.设置每一个li元素宽度240
clearTimeout(timeID)
timeID = setTimeout(function () {
for (let i = 0; i < liList.length; i++) {
liList[i].style.width = '240px'
}
}, 300)
}
函数节流
什么是函数节流 : 间隔时间内函数只被触发一次
函数节流作用: 降低高频事件的触发频率
高频事件: 触发频率很高的事件 如 : onmousemove onscroll
函数节流思路:
- 声明变量存储本次触发的时间time
- 每一次触发的时候, 使用 当前时间 - time,判断两次间隔是否超过 节流时间
超过: 触发,并且存储本次触发时间。
不超过:不触发
示例 :
//节流第一步: 存储变量记录触发时间
let time = null
let i = 1
//高频事件:鼠标移动
window.onmousemove = function () {
//节流第二步: 判断两次间隔是否超过 节流时间
let currentTime = Date.now()
if( currentTime - time >= 10000 ){
i++
console.log('鼠标移动触发次数:' + i )
//节流第三步: 存储本次触发时间
time = currentTime
}
}
// let j = 1
//高频事件:鼠标滚动
// window.onscroll = function(){
// j++
// console.log('鼠标滚动条触发次数:' + j )
// }
函数的防抖与节流总结
函数防抖及应用场景:
- 函数防抖 : 间隔时间 内多次触发事件以最后一次为准
- 应用场景 : 鼠标移入/移出 、 键盘输入框
函数节流及应用场景:
- 函数节流 : 间隔时间 内事件只会触发一次
- 应用场景 : 高频事件 鼠标移动 鼠标滚动条
防抖与节流异同点 :
相同点: 都是为了优化函数执行频率,提高网页性能
不同点:
- 防抖: 优化‘用户主动‘触发的事件, 多次触发以最后一次为准
- 节流: 优化‘事件本身’执行的频率, 间隔时间只执行一次
搜索框防抖案例
<input type="text" placeholder="请输入搜索内容" />
<script>
let timeID = null
document.querySelector('input').oninput = function () {
//清除上一次定时器,以本次为准
clearTimeout(timeID)
//开启本次防抖定时器
/*
细节:定时器中的this,默认指向window
如果定时器函数是箭头函数,则会访问上一次this : 事件源
*/
timeID = setTimeout(()=>{
console.log(this.value)
},300)
}
</script>