小編給大家分享一下JavaScript中節(jié)流的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

前言
我們來聊一聊節(jié)流——另一個優(yōu)化函數(shù)的思想。
我們還是以移動事件舉例
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#wrapper {
width: 100%;
height: 140px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
font-size: 30px;
font-weight: bold;
line-height: 140px;
text-align: center;
}
</style></head><body>
<p id="wrapper"></p>
<script>
var count = 1;
function moveAction () {
oWrapper.innerHTML = count++;
}
var oWrapper = document.querySelector('#wrapper');
oWrapper.onmousemove = moveAction;
</script></body></html>它的效果是這樣:

一、核心和基本實(shí)現(xiàn)
節(jié)流的原理很簡單:如果你持續(xù)觸發(fā)某個事件,特定的時間間隔內(nèi),只執(zhí)行一次。
關(guān)于節(jié)流的實(shí)現(xiàn),有兩種主流的實(shí)現(xiàn)方式:
時間戳思路
定時器思路
顧名思義,通過兩個時間戳來控制時間間隔,當(dāng)觸發(fā)事件的時候:
我們?nèi)〕霎?dāng)前的時間戳now;
然后減去之前執(zhí)行時的時間戳(首次值為 0 )prev;
如果大now - prev > wait,證明時間區(qū)間維護(hù)結(jié)束,執(zhí)行指定事件,更新prev;
根據(jù)這一思路,我們就可以實(shí)現(xiàn)第一版代碼了:
oWrapper.onmousemove = throttle(moveAction, 1000);function throttle(func, wait) {
var _this, arg;
var prev = 0; // 上一次觸發(fā)的時間,第一次默認(rèn)為0
return function () {
var now = Date.now(); // 觸發(fā)時的時間
_this = this;
if (now - prev > wait) {
func.apply(_this, arg); // 允許傳入?yún)?shù),并修正this
prev = now; // 更新上一次觸發(fā)的時間
}
}}來看看借助它,效果是什么樣的:

我們可以看到:
當(dāng)鼠標(biāo)移入的時候,事件立刻執(zhí)行
每過 1s 會執(zhí)行一次,且移動2.5s會執(zhí)行2次,意味著動作停止后不會再執(zhí)行。
利用定時器來保證間隔時間內(nèi)事件的觸發(fā)次數(shù)
創(chuàng)建定時器timer,記錄當(dāng)前是否在周期內(nèi);
判斷定時器是否存在,若存在則直接結(jié)束,否則執(zhí)行事件;
wait時間之后再次執(zhí)行,并清掉定時器;
當(dāng)觸發(fā)事件的時候,我們設(shè)置一個定時器,再觸發(fā)事件的時候,如果定時器存在,就不執(zhí)行,直到定時器執(zhí)行,然后執(zhí)行函數(shù),清空定時器,這樣就可以設(shè)置下個定時器。
function throttle(func, wait) {
var _this, arg;
var timer; // 初始化
return function () {
_this = this; // 記錄this
arg = arguments; // 記錄參數(shù)數(shù)組
if (timer) return; // 時候未到
timer = setTimeout(() => {
func.apply(_this, arg); // 允許傳入?yún)?shù),并修正this
timer = null;
}, wait);
}}來看看借助它,效果是什么樣的:

但是,我們可以看到:
當(dāng)鼠標(biāo)移入的時候,事件不會立刻執(zhí)行;
鼠標(biāo)定制后wait間隔后會執(zhí)行一次
| 時間戳 | 定時器 | |
|---|---|---|
| “起點(diǎn)” | 立即執(zhí)行 | n 秒后執(zhí)行 |
| “終點(diǎn)” | 停止后不會執(zhí)行 | 停止會再執(zhí)行一次 |
二、節(jié)流進(jìn)階
結(jié)合兩種思想完成一個可以立即執(zhí)行,且停止觸發(fā)后再執(zhí)行一次的節(jié)流方法:
// 第三版function throttle(func, wait) {
var timeout, context, args, result;
var previous = 0;
var later = function() {
previous = +new Date();
timeout = null;
func.apply(context, args)
};
var throttled = function() {
var now = +new Date();
//下次觸發(fā) func 剩余的時間
var remaining = wait - (now - previous);
context = this;
args = arguments;
// 如果沒有剩余的時間了或者你改了系統(tǒng)時間
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(context, args);
} else if (!timeout) {
timeout = setTimeout(later, remaining);
}
};
return throttled;}效果演示如下:

我在看代碼的時候,我是反復(fù)打印數(shù)據(jù)才理解為什么會這樣做,一起加油~
以上是“JavaScript中節(jié)流的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
本文題目:JavaScript中節(jié)流的示例分析-創(chuàng)新互聯(lián)
地址分享:http://chinadenli.net/article48/ddhdep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、靜態(tài)網(wǎng)站、營銷型網(wǎng)站建設(shè)、Google、動態(tài)網(wǎng)站、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容