相关链接
1. js防抖和节流
2. 函数防抖和节流
3. JS的防抖与节流
4. JavaScript专题之跟着underscore学防抖
5. 分时函数 & 节流函数
一、防抖
1-1. 【非立即执行】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="demo"></div>
<script type="text/javascript">
// 防抖
function debounce(fn, wait) {
var timeout = null;
return function() {
if (timeout !== null) clearTimeout(timeout);
timeout = setTimeout(fn, wait);
}
}
// 处理函数
function handle() {
document.getElementById('demo').innerHTML = Math.random();
}
// 滚动事件
window.addEventListener('mousemove', debounce(handle, 1000));
// 未防抖
// window.addEventListener('mousemove', handle);
</script>
</body>
</html>
1-2. 【非立即执行】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="demo"></div>
<script type="text/javascript">
// 防抖
function debounce(fn, wait) {
var timeout = null;
return function() {
var context = this;
var args = arguments;
if (timeout !== null) clearTimeout(timeout);
timeout = setTimeout(function() {
fn.apply(context, args);
}, wait);
}
}
// 处理函数
function handle() {
document.getElementById('demo').innerHTML = Math.random();
}
// 鼠标移动事件
window.addEventListener('mousemove', debounce(handle, 1000));
// 未防抖
// window.addEventListener('mousemove', handle);
</script>
</body>
</html>
2. 【立即执行】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="demo"></div>
<script type="text/javascript">
// 防抖
function debounce(fn, wait) {
var timeout = null;
return function() {
var context = this;
var args = arguments;
if (timeout) clearTimeout(timeout);
var callNow = !timeout;
timeout = setTimeout(function() {
timeout = null;
}, wait);
if (callNow) fn.apply(context, args);
}
}
// 处理函数
function handle() {
document.getElementById('demo').innerHTML = Math.random();
}
// 滚动事件
window.addEventListener('mousemove', debounce(handle, 1000));
// 未防抖
// window.addEventListener('mousemove', handle);
</script>
</body>
</html>
3. 【二合一】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="demo"></div>
<script type="text/javascript">
/**
* @desc 函数防抖
* @param func 函数
* @param wait 延迟执行毫秒数
* @param immediate true 表立即执行,false 表非立即执行
*/
// 防抖
function debounce(fn, wait, immediate) {
var timeout = null;
return function() {
var context = this;
var args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(function() {
timeout = null;
}, wait);
if (callNow) fn.apply(context, args);
} else {
timeout = setTimeout(function() {
fn.apply(context, args);
}, wait);
}
}
}
// 处理函数
function handle() {
document.getElementById('demo').innerHTML = Math.random();
}
// 立即执行
window.addEventListener('mousemove', debounce(handle, 1000, true));
// 非立即执行
// window.addEventListener('mousemove', debounce(handle, 1000, false));
</script>
</body>
</html>
二、节流
1. 【时间戳】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="demo"></div>
<script type="text/javascript">
// 节流
function throttle(fn, wait) {
var previous = 0;
return function() {
var now = Date.now();
var context = this;
var args = arguments;
if (now - previous >= wait) {
fn.apply(context, args);
previous = now;
}
}
}
// 处理函数
function handle() {
document.getElementById('demo').innerHTML = Math.random();
}
// 滚动事件
window.addEventListener('mousemove', throttle(handle, 1000));
// 未防抖
// window.addEventListener('mousemove', handle);
</script>
</body>
</html>
2. 【定时器】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="demo"></div>
<script type="text/javascript">
// 节流
function throttle(fn, wait) {
var timeout = null;
return function() {
var context = this;
var args = arguments;
if (!timeout) {
timeout = setTimeout(function() {
timeout = null;
fn.apply(context, args);
}, wait);
}
}
}
// 处理函数
function handle() {
document.getElementById('demo').innerHTML = Math.random();
}
// 滚动事件
window.addEventListener('mousemove', throttle(handle, 1000));
// 未防抖
// window.addEventListener('mousemove', handle);
</script>
</body>
</html>
3-1. 【二合一】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="demo"></div>
<script type="text/javascript">
// 节流
function throttle(fn, wait) {
var timeout = null;
var startTime = Date.now();
return function() {
var curTime = Date.now();
var remaining = wait - (curTime - startTime);
var context = this;
var args = arguments;
clearTimeout(timeout);
if (remaining <= 0) {
fn.apply(context, args);
startTime = Date.now();
} else {
timeout = setTimeout(fn, remaining);
}
}
}
// 处理函数
function handle() {
document.getElementById('demo').innerHTML = Math.random();
}
// 滚动事件
window.addEventListener('mousemove', throttle(handle, 1000));
// 未防抖
// window.addEventListener('mousemove', handle);
</script>
</body>
</html>
3-2. 【二合一】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="demo"></div>
<script type="text/javascript">
// 节流
function throttle(fn, wait, type) {
if (type === 1) {
var previous = 0;
} else if (type === 2) {
var timeout = null;
}
return function() {
var context = this;
var args = arguments;
if (type === 1) {
var now = Date.now();
if (now - previous >= wait) {
fn.apply(context, args);
previous = now;
}
} else if (type === 2) {
if (!timeout) {
timeout = setTimeout(function() {
timeout = null;
fn.apply(context, args);
}, wait);
}
}
}
}
// 处理函数
function handle() {
document.getElementById('demo').innerHTML = Math.random();
}
// 时间戳节流
window.addEventListener('mousemove', throttle(handle, 1000, 1));
// 定时器节流
// window.addEventListener('mousemove', throttle(handle, 1000, 2));
</script>
</body>
</html>
三、分时
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="demo"></div>
<script type="text/javascript">
/**
* @desc 分时函数
* @param ary 批量操作所需要的数据集
* @param fn 封装了批量操作的逻辑函数
* @param count 每批操作的数据的数量
* @param wait 分批执行的时间间隔
*/
// 分时
function timeChunk(ary, fn, count, wait) {
var timeout = null;
var start = function() {
for (var i = 0; i < Math.min(count || 1, ary.length); i++) {
var obj = ary.shift();
fn(obj);
}
}
return function() {
timeout = setInterval(function() {
if (ary.length === 0) return clearInterval(timeout);
start();
}, wait);
}
}
var arr = [];
for (var i = 1; i <= 100; i++) {
var span = document.createElement('span');
span.style.padding = '6px 12px';
if (i%10 === 0) {
span.innerHTML = i + '<br />';
} else {
span.innerHTML = i;
}
arr.push(span);
}
var fn = function(ele) {
document.getElementById('demo').appendChild(ele);
}
timeChunk(arr, fn, 10, 1000)();
</script>
</body>
</html>