节流:
对于短时间内连续触发的事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效;
防抖:
对于短时间内连续触发的事件,让某个时间期限(如1000毫秒)内,事件处理函数只执行一次。
节流
:指定时间间隔内只会执行一次函数
判断页面是否滚动到底部为例
function onScroll() {
// 判断是否滚动到底部的逻辑
const pageHeight = $('body').height();
const scrollTop = $(window).scrollTop();
const winHeight = $(window).height();
const thresold = pageHeight - scrollTop - winHeight;
if (thresold > -100 && thresold <= 20) {
console.log('end');
}
}
$(window).on('scroll', onScroll);
在滚动时,每隔一段时间去计算这个判断逻辑。如果一直拖着滚动条进行滚动,那么会以1s的时间间隔,持续输出当前位置和顶部的距离
$(window).on('scroll', throttle(function () {
// 判断是否滚动到底部的逻辑
const pageHeight = $('body').height();
const scrollTop = $(window).scrollTop();
const winHeight = $(window).height();
const thresold = pageHeight - scrollTop - winHeight;
if (thresold > -100 && thresold <= 20) {
console.log('end');
}
}));
function throttle(fn, interval = 1000) {
let canRun = true;
return function () {
if (!canRun) return;
canRun = false;
setTimeout(() => {
fn.apply(this, arguments);
canRun = true;
}, interval);
};
}
function throttle(fn,delay){
let valid = true
return function() {
if(!valid){
//休息时间 暂不接客
return false
}
// 工作时间,执行函数并且在间隔期内把状态位设为无效
valid = false
setTimeout(() => {
fn()
valid = true;
}, delay)
}
}
/* 请注意,节流函数并不止上面这种实现方案,
例如可以完全不借助setTimeout,可以把状态位换成时间戳,然后利用时间戳差值是否大于指定间隔时间来做判定。
也可以直接将setTimeout的返回的标记当做判断条件-判断当前定时器是否存在,如果存在表示还在冷却,并且在执行fn之后消除定时器表示激活,原理都一样
*/
// 以下照旧
function showTop () {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = throttle(showTop,1000)
防抖:
函数频繁触发的情况下,只有函数触发的间隔超过指定间隔的时候,任务才会执行。
function debounce(fn,delay){
let timer = null //借助闭包
return function() {
if(timer){
clearTimeout(timer)
}
timer = setTimeout(fn,delay) // 简化写法
}
}
// 然后是旧代码
function showTop () {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = debounce(showTop,1000) // 为了方便观察效果我们取个大点的间断值,实际使用根据需要来配置
vue防抖
<input v-model="inVal" placeholder="输入……">
<script>
const delay=(function(){
let timer=0;
return function(callback,ms){
clearTimeout(timer)
timer = setTimeout(callback,ms)
}
})()
export default{
watch: {
inpVal: function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
delay(() =>{
// 具体函数
},1000)
}
}
}
</script>