防抖
短时间内大量触发,只执行一次,若这段事件内再次触发,则重新计时
<!DOCTYPE html>
<html>
<head>
<title> </title>
</head>
<body>
<input type="text" id="inputText">
</body>
<script type="text/javascript">
document.querySelector("#inputText").addEventListener('input',
debounce(function(){
console.log(this.value)
}, 3000, true)
)
function debounce(fn, delay, isImmediate) {
var timer = null; // 初始化timer,作为计时器清除依据
return function () {
var context = this; // 获取函数所在作用域this
var args = arguments; // 取得传入的参数
timer && clearTimeout(timer)
if (isImmediate && timer === null) {
// 时间间隔外立即执行
fn.apply(context, args);
timer = 0;
return;
}
timer = setTimeout(function() {
fn.apply(context, args);
timer = null;
}, delay)
}
}
</script>
</html>
节流
短时间触发同一事件,那么在函数执行一次后,该函数在指定期间内不在工作,直到过了时间段
// 时间戳实现
function throttle(fn, delay) {
var prev = Date.now();
return function () {
var context = this;
var args = arguments;
var now = Date.now();
if (now-pre >= delay) {
fn.apply(context, args);
prev = Date.now();
}
}
}
// 定时器
function throttle(fn, delay) {
var timer = null;
var args = arguments;
if (timer === null) {
timer = setTimeout(function () {
fn.apply(context, args);
timer = null;
})
}
}
<!DOCTYPE html>
<html>
<head>
<title> </title>
</head>
<body>
<input type="text" id="inputText">
<div id="blackpanel" style="background: gray; width: 500px; height: 500px">
<span id="num"></span>
</div>
</body>
<script type="text/javascript">
var count = 0;
document.querySelector("#blackpanel").onmouseover = throttle(showNum, 3000,
{"leading": false, "trailing": true})
function showNum () {
count = count +1
document.querySelector("#num").innerHTML = count
}
// 时间戳 + 定时器
// options = {leading: false, trailing:false} leading: 首次是否执行,trailing 结束后是否执行
function throttle(fn, delay, options) {
var timeout, context, args, result;
var previous = 0; // 开始时间
if (!options) options = {};
var later = function () {
previous = options.leading === false ? 0 : Date.now()
timeout = null;
result = fn.apply(context, args);
if(!timeout) context=args=null;
}
var throttled = function() {
var now = Date.now()
if(!previous && options.leading===false) previous = now; // 是否首次执行
var remaining = delay - (now - previous) // 下次触发fn剩余事件,假设delay事件很大,则remaining为正数
context = this;
args = arguments;
if (remaining <= 0 || remaining > delay) { // 如果没有剩余事件或者改了系统时间
if (timeout) {
clearTimeout(timeout)
timeout = null
}
previous = now;
fn.apply(context, args)
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) { // 是否结束后还执行
timeout = setTimeout(later, remaining); // setTiemout中remaining 超过最大值,则会立即执行
}
}
return throttled
}
</script>
</html>
网友评论