JavaScript中節(jié)流的示例分析-創(chuàng)新互聯(lián)

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

創(chuàng)新互聯(lián)建站堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的昆都侖網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

前言

我們來(lái)聊一聊節(jié)流——另一個(gè)優(yōu)化函數(shù)的思想。

我們還是以移動(dòng)事件舉例

<!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>

它的效果是這樣:

JavaScript中節(jié)流的示例分析

一、核心和基本實(shí)現(xiàn)

節(jié)流的原理很簡(jiǎn)單:如果你持續(xù)觸發(fā)某個(gè)事件,特定的時(shí)間間隔內(nèi),只執(zhí)行一次。

關(guān)于節(jié)流的實(shí)現(xiàn),有兩種主流的實(shí)現(xiàn)方式:

  1. 時(shí)間戳思路

  2. 定時(shí)器思路

1.1 時(shí)間戳思路

顧名思義,通過(guò)兩個(gè)時(shí)間戳來(lái)控制時(shí)間間隔,當(dāng)觸發(fā)事件的時(shí)候:

  1. 我們?nèi)〕霎?dāng)前的時(shí)間戳now;

  2. 然后減去之前執(zhí)行時(shí)的時(shí)間戳(首次值為 0 )prev;

  3. 如果大now - prev > wait,證明時(shí)間區(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ā)的時(shí)間,第一次默認(rèn)為0

    return function () {
        var now = Date.now(); // 觸發(fā)時(shí)的時(shí)間
        _this = this;
        if (now - prev > wait) {
            func.apply(_this, arg); // 允許傳入?yún)?shù),并修正this
            prev = now; // 更新上一次觸發(fā)的時(shí)間
        }
    }}

來(lái)看看借助它,效果是什么樣的:

JavaScript中節(jié)流的示例分析

我們可以看到:

  1. 當(dāng)鼠標(biāo)移入的時(shí)候,事件立刻執(zhí)行

  2. 每過(guò) 1s 會(huì)執(zhí)行一次,且移動(dòng)2.5s會(huì)執(zhí)行2次,意味著動(dòng)作停止后不會(huì)再執(zhí)行

1.2 定時(shí)器思路

利用定時(shí)器來(lái)保證間隔時(shí)間內(nèi)事件的觸發(fā)次數(shù)

  1. 創(chuàng)建定時(shí)器timer,記錄當(dāng)前是否在周期內(nèi);

  2. 判斷定時(shí)器是否存在,若存在則直接結(jié)束,否則執(zhí)行事件;

  3. wait時(shí)間之后再次執(zhí)行,并清掉定時(shí)器;

當(dāng)觸發(fā)事件的時(shí)候,我們?cè)O(shè)置一個(gè)定時(shí)器,再觸發(fā)事件的時(shí)候,如果定時(shí)器存在,就不執(zhí)行,直到定時(shí)器執(zhí)行,然后執(zhí)行函數(shù),清空定時(shí)器,這樣就可以設(shè)置下個(gè)定時(shí)器。

function throttle(func, wait) {
    var _this, arg;
    var timer; // 初始化
    return function () {
        _this = this; // 記錄this
        arg = arguments; // 記錄參數(shù)數(shù)組
        if (timer) return; // 時(shí)候未到
        timer = setTimeout(() => {
            func.apply(_this, arg); // 允許傳入?yún)?shù),并修正this
            timer = null;
        }, wait);
    }}

來(lái)看看借助它,效果是什么樣的:

JavaScript中節(jié)流的示例分析

但是,我們可以看到:

  1. 當(dāng)鼠標(biāo)移入的時(shí)候,事件不會(huì)立刻執(zhí)行;

  2. 鼠標(biāo)定制后wait間隔后會(huì)執(zhí)行一次

1.3 兩種思路的區(qū)別

時(shí)間戳定時(shí)器
“起點(diǎn)”立即執(zhí)行n 秒后執(zhí)行
“終點(diǎn)”停止后不會(huì)執(zhí)行停止會(huì)再執(zhí)行一次

二、節(jié)流進(jìn)階

結(jié)合兩種思想完成一個(gè)可以立即執(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 剩余的時(shí)間
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
         // 如果沒(méi)有剩余的時(shí)間了或者你改了系統(tǒng)時(shí)間
        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;}

效果演示如下:

JavaScript中節(jié)流的示例分析

我在看代碼的時(shí)候,我是反復(fù)打印數(shù)據(jù)才理解為什么會(huì)這樣做,一起加油~

以上是“JavaScript中節(jié)流的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

本文題目:JavaScript中節(jié)流的示例分析-創(chuàng)新互聯(lián)
地址分享:http://muchs.cn/article48/ddhdep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、靜態(tài)網(wǎng)站、營(yíng)銷型網(wǎng)站建設(shè)、Google、動(dòng)態(tài)網(wǎng)站、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化