亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript節流與防抖實例分析

發布時間:2022-04-06 11:01:22 來源:億速云 閱讀:139 作者:iii 欄目:開發技術

本篇內容主要講解“JavaScript節流與防抖實例分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JavaScript節流與防抖實例分析”吧!

    一、js防抖和節流

    在進行窗口的resize、scroll、輸出框內容校驗等操縱的時候,如果事件處理函數調用的頻率無限制,會加重瀏覽器的負擔,導致用戶體驗非常之差。那么為了前端性能的優化也為了用戶更好的體驗,就可以采用防抖(debounce)和節流(throttle)的方式來到達這種效果,減少調用的頻率。

    二、為什么滾動scroll、窗口resize等事件需要優化

    滾動事件的應用很頻繁:圖片懶加載、下滑自動加載數據、側邊浮動導航欄等。

    在綁定scroll、resize事件時,但它發生的時候,它被觸發的頻率非常高,間隔很近。在日常開發的頁面中,事件中涉及到的大量的位置計算、DOM操作、元素重繪等等這些都無法在下一個scroll事件出發前完成的情況下,瀏覽器會卡幀。

    三、滾動和頁面渲染前端性能優化的關系

    為什么滾動需要優化?前面提到了事件中涉及到大量的位置計算、DOM操作、元素重繪等等,這些又與頁面的渲染有關系,頁面渲染又與前端的性能優化有關系?套娃一樣,一層套著一層,每一層都聯系緊密,每一層都如此平凡且重要。

    review一下前端的渲染和優化

    網頁生成的時候,至少會渲染(Layout+Paint)一次。用戶訪問的過程中,還會不斷重新的重排(reflow)和重繪(repaint),用戶scroll行為和resize行為會導致頁面不斷的進行重新渲染,而且間隔頻繁,容易造成瀏覽器卡幀。

    四、防抖Debounce

    1 防抖Debounce情景

    ①有些場景事件觸發的頻率過高(mousemove onkeydown onkeyup onscroll)

    ②回調函數執行的頻率過高也會有卡頓現象。 可以一段時間過后進行觸發去除無用操作

    2 防抖原理

    一定在事件觸發 n 秒后才執行,如果在一個事件觸發的 n 秒內又觸發了這個事件,以新的事件的時間為準,n 秒后才執行,等觸發事件 n 秒內不再觸發事件才執行。

    官方解釋:當持續觸發事件時,一定時間段內沒有再觸發事件,事件處理函數才會執行一次,如果設定的時間到來之前,又一次觸發了事件,就重新開始延時。

    3 防抖函數簡單實現

        //簡單的防抖函數
        function debounce(func, wait, immediate) {
            //定時器變量
            var timeout;
            return function () {
                //每次觸發scrolle,先清除定時器
                clearTimeout(timeout);
                //指定多少秒后觸發事件操作handler
                timeout = setTimeout(func, wait);
            };
        };
        //綁定在scrolle事件上的handler
        function handlerFunc() {
            console.log('Success');
        }
        //沒采用防抖動
        window.addEventListener('scroll', handlerFunc);
        //采用防抖動
        window.addEventListener('scrolle', debounce(handlerFunc, 1000));

    4 防抖函數的演化過程

    ①this event綁定問題
        //以閉包的形式返回一個函數,內部解決了this指向的問題,event對象傳遞的問題
        function debounce(func, wait) {
            var timeout;
            return function () {
                var context = this;
                var args = arguments;
                clearTimeout(timeout)
                timeout = setTimeout(function () {
                    func.apply(context, args)
                }, wait);
            };
        };
    ②立即觸發問題
        //首次觸發執行,再次觸發以后開始執行防抖函數
        //使用的時候不用重復執行這個函數,本身返回的函數才具有防抖功能
    function debounce(func, wait, immediate) {
        var timeout;
        return function () {
            var context = this;
            var args = arguments;
            
            if(timeout) clearTimeout(timeout);
            // 是否在某一批事件中首次執行
            if (immediate) {
                var callNow = !timeout;
                timeout = setTimeout(function() {
                    timeout = null;
                    func.apply(context, args)
                    immediate = true;
                }, wait);
                if (callNow) {
                    func.apply(context, args)
                }
                immediate = false;
            } else {
                timeout = setTimeout(function() {
                    func.apply(context, args);
                    immediate = true;
                }, wait);
            }
        }
    }
    ③返回值問題
    function debounce(func, wait, immediate) {
        var timeout, result;
        return function () {
            var context = this, args = arguments;
            if (timeout)  clearTimeout(timeout);
            if (immediate) {
                var callNow = !timeout;
                timeout = setTimeout(function() {
                    result = func.apply(context, args)
                }, wait);
                if (callNow) result = func.apply(context, args);
            } else {
                timeout = setTimeout(function() {
                    result = func.apply(context, args)
                }, wait);
            }
            return result;
        }
    }
    ④取消防抖,添加cancel方法
    function debounce(func, wait, immediate) {
        var timeout, result;
        function debounced () {
            var context = this, args = arguments;
            if (timeout)  clearTimeout(timeout);
            if (immediate) {
                var callNow = !timeout;
                timeout = setTimeout(function() {
                    result = func.apply(context, args)
                }, wait);
                if (callNow) result = func.apply(context, args);
            } else {
                timeout = setTimeout(function() {
                    result = func.apply(context, args)
                }, wait);
            }
            return result;
        }
        debounced.cancel = function(){
            cleatTimeout(timeout);
            timeout = null;
        }
        return debounced;
    }

    五、節流Throttle

    1 節流Throttle情景

    ①圖片懶加載

    ②ajax數據請求加載

    2 節流原理

    如果持續觸發事件,每隔一段時間只執行一次函數。

    官方解釋:當持續觸發事件時,保證一定時間段內只調用一次事件處理函數。

    3 節流實現—時間戳和定時器

    時間戳

        var throttle = function (func, delay) {
            var prev = Date.now()
            return function () {
                var context = this;
                var args = arguments;
                var now = Date.now();
                if (now - prev >= delay) {
                    func.apply(context, args);
                    prev = Date.now();
                }
            }
        }
    
        function handle() {
            console.log(Math.random());
        }
        window.addEventListener('scroll', throttle(handle, 1000));

    定時器

        var throttle = function (func, delay) {
            var timer = null;
            return function () {
                var context = this;
                var args = arguments;
                if (!timer) {
                    timer = setTimeout(function () {
                        func.apply(context, args);
                        timer = null;
                    }, delay);
                }
            }
        }
    
        function handle() {
            console.log(Math.random());
        }
        window.addEventListener('scroll', throttle(handle, 1000))

    4 節流函數的演化過程

    ①時間戳觸發
    //在開始觸發時,會立即執行一次; 如果最后一次沒有超過 wait 值,則不觸發
    function throttle(func, wait) {
        var context, args;
        var previous = 0; // 初始的時間點,也是關鍵的時間點
    
        return function() {
            var now = +new Date();
            context = this;
            args = arguments;
            if (now - previous > wait) {
                func.apply(context, args);
                previous = now;
            }
        }
    }
    ②定時器觸發
    //首次不會立即執行,最后一次會執行,和用時間戳的寫法互補。
    function throttle(func, wait){
        var context, args, timeout;
        return function() {
            context = this;
            args = arguments;
            if(!timeout) {
                timeout = setTimeout(function(){
                    func.apply(context, args);
                    timeout = null;
                }, wait);
            }
        }
    }
    ③結合時間戳和定時器
    function throttle(func, wait) {
    
        var timer = null;
        var startTime = Date.now();  
    
        return function(){
            var curTime = Date.now();
            var remaining = wait-(curTime-startTime); 
            var context = this;
            var args = arguments;
    
            clearTimeout(timer);
    
            if(remaining<=0){ 
                func.apply(context, args);
    
                startTime = Date.now();
    
            }else{
                timer = setTimeout(fun, remaining);  // 如果小于wait 保證在差值時間后執行
            }
        }
    }

    到此,相信大家對“JavaScript節流與防抖實例分析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    舞阳县| 郴州市| 新巴尔虎左旗| 昔阳县| 泌阳县| 谷城县| 潜山县| 五原县| 措勤县| 乐安县| 太仆寺旗| 会泽县| 红原县| 莫力| 舒兰市| 光山县| 聂拉木县| 连云港市| 海丰县| 十堰市| 黄石市| 南靖县| 花垣县| 永丰县| 永泰县| 奉贤区| 满洲里市| 平山县| 三原县| 府谷县| 内江市| 龙山县| 库车县| 卫辉市| 基隆市| 三门峡市| 阿鲁科尔沁旗| 开鲁县| 华容县| 葵青区| 洪泽县|