手写函数防抖节流
DOM 0级事件
<style>
.demo{width:200px;height:200px;border:1px solid red;overflow-y:scroll;margin-top:50px;}
.scroll{height:5000px;}
</style>
</head>
<body>
<div class="wrap">
<div id="nothing" class="demo">
普通滚动
<div class="scroll"></div>
</div>
<div id="throttle" class="demo">
函数节流
<div class="scroll"></div>
</div>
<div id="debounce" class="demo">
函数防抖
<div class="scroll"></div>
</div>
</div>
<script type="text/javascript">
// 普通滚动
document.getElementById("nothing").onscroll = function(){
console.log("普通滚动");
};
// 函数节流
var canRun = true;
document.getElementById("throttle").onscroll = function(){
if(!canRun){
// 判断是否已空闲,如果在执行中,则直接return
return;
}
canRun = false;
setTimeout(function(){
console.log("函数节流");
canRun = true;
}, 300);
};
// 函数防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){
clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
timer = setTimeout(function(){
console.log("函数防抖");
}, 300);
};
</script>
</body>
</html>
DOM 2级事件 事件监听
document.addEventListener('scroll', debounce(test, 300))
function test() {
console.log('函数...')
}
函数防抖(debounce)
function debounce(fn, delay) {
let timer;
return function() {
let context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
};
}
函数节流(throttle)
// 方法一:定时器实现
const throttle = function(fn,delay) {
let timer = null
return function() {
const context = this
let args = arguments
if(!timer) {
timer = setTimeout(() => {
fn.apply(context,args)
clearTimeout(timer)
timer = null;
},delay)
}
}
}
// 方法二:时间戳
const throttle2 = function(fn, delay) {
let preTime = Date.now()
return function() {
const context = this
let args = arguments
let doTime = Date.now()
if (doTime - preTime >= delay) {
fn.apply(context, args)
preTime = Date.now()
}
}
}