卡顿现象:
正常:事件触发非常频繁,每一次触发,回调函数都会执行,如果时间很短,回调函数中有计算,有可能会出现浏览器卡顿
节流:(执行一次,规定的时间内不再触发)在规定的时间间隔范围内,不会触发多次回调,只有大于这个时间才会触发回调。频繁触发 => 少量触发
防抖:(重置时间执行最后一次)前面所有的触发都会取消,最后一次的执行在规定的时间之后才会触发 频繁触 => 只执行一次
方式一: lodash插件:
lodash向外暴露的是_.+函数名()
防抖: _.debounce(fn,waitTime,option)
节流: _.throttle(fn,waitTime,option)
npm i --save lodash // 安装第三方插件
import _ from 'lodash'
export default {
methods: {
//触发的事件 这里不能用箭头函数 因为箭头函数没有自身的this
scrolls:_.debounce(function (event) {
console.log(event.target.scrollTop)
if(event.target.scrollTop > 0){
this.changeStyle = true;
}else{
this.changeStyle = false;
}
}, 200)
}
}
深入解析: 深入篇 | Lodash 防抖和节流是怎么实现的_51CTO博客_vue lodash防抖
方式二: 定时器和高阶函数(手写):
/**
* 第三个参数可控制是首次触发还是时间结束触发
* @param {Function} func
* @param {Number} wait
* @param {Boolean} immed
* @returns
*/
function debounce (func, wait, immed) {
let timer
return function (...params) {
if (timer) clearTimeout(timer)
if (immed) {
let flag = !immed
timer = setTimeout(() => {
timer = null
}, wait)
if (flag) func.apply(this, params)
} else {
timer = setTimeout(() => {
func.apply(this, params)
}, wait)
}
}
}
/**
*
* @param {Function} func
* @param {Number} wait
* @returns
*/
function throttle (func, wait) {
let sta = 0
let timer
return function (...args) {
let nowTime = new Date().getTime()
let res = wait - (nowTime - sta)
if (timer) clearTimeout(timer)
if (res <= 0) {
func.apply(this, args)
sta = nowTime
} else {
timer = setTimeout(() => {
func.apply(this, args)
sta = nowTime
}, res)
}
}
}