一、實現(xiàn)防抖:在事件被觸發(fā)n秒后再執(zhí)行回調(diào),如果在這n秒內(nèi)又被觸發(fā),則重新計時。
比如說一個倒計時按鈕,倒計時10秒,過了兩秒,有人再次觸發(fā)按鈕,又要重新計時,再等10秒。
實現(xiàn)防抖思路:通過閉包維護一個變量,此變量代表是否已經(jīng)開始計時,如果已經(jīng)開始計時則清空之前計時器,重新計時。
<script>
// 首先閉包里面要有一個變量,這個變量是個計時器,
// 我們要判斷這個計時器是否已經(jīng)計時了,如果已經(jīng)
// 計時了我們就把原先的清空掉
// 不管有沒有計時器,我們設(shè)置一個計時器,然后把函數(shù)和時間傳進來
// 傳進來的函數(shù)有參數(shù),還有this指向,用arguments和apply
function debounce(fn, time) {
let timer = null;
return function() {
let args = arguments;
let context = this;
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(function() {
fn.apply(context, args);
}, time);
};
}
function test(num) {
console.log(num);
console.log(this);
}
let newFn = debounce(test, 1000);
window.onscroll = function() {
newFn(123);
};
</script>
// 這個案例就是展示搜索框內(nèi)容提示,為避免不必要的請求,設(shè)置一個定時器,
// 800 毫秒向服務(wù)器發(fā)送一次請求,如果期間文本框值發(fā)生變化,則清空計時器,不發(fā)送請求。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>搜索框輸入文字自動提示</title>
<link
rel="stylesheet"
href="/assets/bootstrap/dist/css/bootstrap.min.css"
/>
<style type="text/css">
.container {
padding-top: 150px;
}
.list-group {
display: none;
}
</style>
</head>
<body>
<div class="container">
<div class="form-group">
<input
type="text"
class="form-control"
placeholder="請輸入搜索關(guān)鍵字"
id="search"
/>
<ul class="list-group" id="list-box"></ul>
</div>
</div>
<script src="/js/ajax.js"></script>
<script src="/js/template-web.js"></script>
<script type="text/html" id="tpl">
{{each data}}
<li class="list-group-item">{{$value}}</li>
{{/each}}
</script>
<script>
// 獲取搜索框
var searchInp = document.getElementById("search");
// 獲取提示文字的存放容器
var listBox = document.getElementById("list-box");
// 存儲定時器的變量
var timer = null;
searchInp.oninput = function() {
clearTimeout(timer);
var key = this.value;
if (key.trim().length == 0) {
listBox.style.display = "none";
return;
}
timer = setTimeout(function() {
ajax({
type: "get",
url: "http://localhost:3000/searchAutoPrompt",
data: {
key: key
},
success: function(data) {
var html = template("tpl", { data: data });
console.log(data);
listBox.innerHTML = html;
listBox.style.display = "block";
}
});
}, 600);
};
</script>
</body>
</html>
二、實現(xiàn)節(jié)流:在一段時間內(nèi),只能有一次觸發(fā)事件的回調(diào)函數(shù)執(zhí)行,如果在同一個單位時間內(nèi)某事件被多次觸發(fā),只能有一次生效。
例如發(fā)送驗證碼倒計時按鈕,必須等夠多少秒后才可以再次發(fā)送。
實現(xiàn)思路:通過閉包維護一個變量,次變量代表是否允許執(zhí)行函數(shù),如果允許則執(zhí)行函數(shù)并且把該變量修改為不允許,并使用定時器在規(guī)定時間后恢復(fù)變量。
<script>
function throttle(fn, time) {
let canRun = true; //是否允許fn 函數(shù)被執(zhí)行
return function() {
if (canRun) {
fn.apply(this, arguments);
canRun = false;
setTimeout(function() {
canRun = true;
}, time);
}
};
}
function test(num) {
console.log(num);
console.log(this.age);
}
let obj = {
age: 18
};
let newFn = throttle(test, 2000);
obj.newFn = newFn;
window.onscroll = function() {
obj.newFn("123");
};
</script>