今天手写一个input校验框,突然想起了防抖与节流,好久不深思,记忆有些模糊,特意写下来,加深一些理解与记忆
首先,防抖动与节流是干什么的?
比如,书写一个input框,你需要手写校验,一般我们的处理方法当你输入完失去焦点,我们来监听失焦事件,再来校验,现在比较流行的校验方式都是你输入完就会校验出错误,可当你每输入一个字符就去校验,明显是不合适的,那我们怎么办呢,那就得用到防抖动了。
还有一个就是滚动加载,这个一般使用比较多,当滚动到某个位置时去请求后台数据,这是可以用节流来实现滚动加载
然后,如何实现
1.防抖(使用定时器,再一段时间在没有触发时,才会执行)
function debounce(fn, wait) { var timeout = null; return function() { if(timeout !== null) clearTimeout(timeout); timeout = setTimeout(fn, wait); } } window.addEventListener('scroll', debounce(test, 1000));
2.节流
时间戳:
var throttle = function(fun, delay) { var prev = Date.now(); return function() { var _this= this; var now = Date.now(); if (now - prev >= delay) { fun.apply(_this, arguments); prev = Date.now(); } } } window.addEventListener('scroll', throttle(test, 1000));
使用计时器,第一次会立即执行函数,但最后一次小于delay时,不会执行
定时器:
var throttle = function(fun, delay) { var timer = null; return function() { var _this = this; if (!timer) { timer = setTimeout(function() { fun.apply(_this , arguments); timer = null; }, delay); } } } window.addEventListener('scroll', throttle(test, 1000));
当第一次触发事件时,不会立即执行函数,而是在delay秒后才执行,当最后一次触发后,由于定时器的delay延迟,还会执行一次函数,有点不完美
时间戳+定时器:
var throttle = function(fun, delay) { var timer = null; var startTime = Date.now(); return function() { var curTime = Date.now(); var t_delay= delay - (curTime - startTime); var _this= this; clearTimeout(timer); if (remaining <= 0) { fun.apply(_this, arguments); startTime = Date.now(); } else { timer = setTimeout(fun, t_delay); } } } window.addEventListener('scroll', throttle(test, 1000));
解决第一次立即执行问题,当最后一次触发,时间小于delay时,使用定时器来完成触发
总结:
防抖:在事件被触发后,一段时间内没有在被触发,执行函数,如果期间又被触发事件,则重新计时
节流:在事件被触发后,保证一段时间内,肯定会被执行一次函数