应用场景:需要频繁请求的地方,例如搜索框搜索
使用第三方框架
underscore.js解决防抖
_.debounce(function,time,true)
function是要防抖函数,time是延迟时间,true为是否延迟执行
使用自定义防抖函数
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="IE=edge, chrome=1">
<title>debounce</title>
<style>
#container {
width: 100%;
height: 200px;
line-height: 200px;
text-align: center;
color: #fff;
background-color: #444;
font-size: 30px;
}
</style>
</head>
<body>
<div id="container"></div>
<button id="button">cancel</button>
<script>
let count = 1;
let container = document.getElementById('container');
function handleUserAction(e) {
console.log(this, e);
container.innerHTML = count++;
// 如果请求需要函数值 这里要打return
// return {
// status: true,
// msg: 'execute success'
// }
}
function debounce(fn, wait, immediate) {
let timeout; // 定时器对象
let result; // handleUserAction函数的执行结
console.log(this); //这里的this指向是window对象
return function () {
console.log(this); //这里的this指向的是div元素,这是因为return 返回函数已经替换了fn传递的函数,fn里的this指向的是div元素
let context = this;
let args = arguments;//修改参数
if (timeout) {
clearTimeout(timeout);
}
if (immediate) {
// 立即执行的话
let callNow = !timeout;
timeout = setTimeout(function () {
timeout = null;
}, wait);
if (callNow) {
result = fn.apply(context, args); //这是是使用apply来改变this的指向,如果不使用debounce函数的时候,this就是container DOM元素;当使用之后,this指向window?(已解决)
//如果不使用debounce函数的时候,handleUserAction的参数就是Event; 使用之后变成undefined?
}
}
else {
// 传统的方式的执行的话
timeout = setTimeout(function () {
console.log(this);
// 由于这里实际上就是一个异步的执行结果,所有此时的result最后每次都会返回的是一个undefined
result = fn.apply(context, args);
}, wait);
}
// 在闭包函数的最后,返回函数执行的结果
// return result;
}
}
container.onmousemove = debounce(handleUserAction, 1000, false);
</script>
</body>
</html>