1.實(shí)現(xiàn)防抖函數(shù)(debounce)
防抖函數(shù)原理:在事件被觸發(fā)n秒后再執(zhí)行回調(diào),如果在這n秒內(nèi)又被觸發(fā),則重新計(jì)時(shí)。
//func 是事件觸發(fā)要執(zhí)行的事件
//delay 是延時(shí)多少時(shí)間
function onbounce(func, delay) {
let times;
let context = this;
return function () {
let args = arguments;
clearTimeout(times);
times = setTimeout(function() {
func.apply(context, args); //改變this的指向 傳遞上下文參數(shù)
},delay);
}
}
//方法二
// 防抖函數(shù)
const debounce = (fn, delay) => {
let timer = null;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
};
簡(jiǎn)略例子 你可以粘到html里運(yùn)行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>防抖函數(shù)</title>
</head>
<!-- css -->
<style>
#box {
margin: 50px auto;
width: 60%;
height: 200px;
background-color: pink;
cursor: pointer;
text-align: center;
line-height: 200px;
color: #fff;
font-size: 20px;
}
</style>
<!-- html -->
<body>
<div id="box"></div>
</body>
<!-- js -->
<script>
window.onload = function() {
var count = 1;
var doc = document.getElementById('box');
console.log(doc);
function getUserAtion(e) {
// console.log(e);
doc.innerHTML = count ++;
}
function onbounce (func, wait) {
var times;
var context = this;
return function(...args) {
clearTimeout(times);
times = setTimeout(function() {
func.apply(context,args);
},wait);
}
}
doc.onmousemove = onbounce(getUserAtion, 2000);
}
</script>
</html>
適用場(chǎng)景:
- 按鈕提交場(chǎng)景:防止多次提交按鈕,只執(zhí)行最后提交的一次
- 服務(wù)端驗(yàn)證場(chǎng)景:表單驗(yàn)證需要服務(wù)端配合,只執(zhí)行一段連續(xù)的輸入事件的最后一次,還有搜索聯(lián)想詞功能類似
2.實(shí)現(xiàn)節(jié)流函數(shù)(throttle)
節(jié)流的原理很簡(jiǎn)單:如果你持續(xù)觸發(fā)事件,每隔一段時(shí)間,只執(zhí)行一次事件。
根據(jù)原理,實(shí)現(xiàn)方式有2種,一種是時(shí)間戳 一種是定時(shí)器
1.時(shí)間戳
使用時(shí)間戳,當(dāng)觸發(fā)事件的時(shí)候,我們?nèi)〕霎?dāng)前的時(shí)間戳,然后減去之前的時(shí)間戳(最一開始值設(shè)為 0 ),如果大于設(shè)置的時(shí)間周期,就執(zhí)行函數(shù),然后更新時(shí)間戳為當(dāng)前的時(shí)間戳,如果小于,就不執(zhí)行。
function throlttle (func, wait) {
var previous = 0;
return (...args)=> {
var now = +new Date();
if(now - previous > wait) {
func.apply(this, args);
previous = now;
}
}
}
2.定時(shí)器
當(dāng)觸發(fā)事件的時(shí)候,我們?cè)O(shè)置一個(gè)定時(shí)器,再觸發(fā)事件的時(shí)候,如果定時(shí)器存在,就不執(zhí)行,直到定時(shí)器執(zhí)行,然后執(zhí)行函數(shù),清空定時(shí)器,這樣就可以設(shè)置下個(gè)定時(shí)器。
function throlttle(func, wait) {
var times;
return (...args)=> {
if(!times) {
times = setTimeout(()=> {
times = null;
func.apply(this, args);
},wait)
}
}
}
適用場(chǎng)景:
- 拖拽場(chǎng)景:固定時(shí)間內(nèi)只執(zhí)行一次,防止超高頻次觸發(fā)位置變動(dòng)
- 縮放場(chǎng)景:監(jiān)控瀏覽器resize
- 動(dòng)畫場(chǎng)景:避免短時(shí)間內(nèi)多次觸發(fā)動(dòng)畫引起性能問題