簡體   English   中英

使用遞歸函數 Vanilla Javascript 節流顯示 div 和子項

[英]Throttle displaying of div and children, using recursive function Vanilla Javascript

最初,我有一個巨大的 div,其中包含許多子元素display: none然后我只需將其設置為display: ''並且整個 div 將可見。 這造成了一些明顯的滯后。 我想通過超時顯示元素來限制它,但是我創建的函數會導致奇怪的行為。 如果您刪除setTimeout但沒有setTimeout仍然存在相同的延遲,它實際上可以正常工作。

function throttleDisplay(page) {
    page.style.display = '';
    var children = page.children;
    if (!children.length) return;
    for (var i = 0; i < children.length; i++) {
        var child = children[i];
        setTimeout(function() {
            throttleDisplay(child);
        }, 100);
    }
}

幾個問題。

  1. 通過設置display:block (或display:'' )一次性display:block頂級<div>將僅觸發一頁重排和重新繪制,因此與遞歸顯示子項相比,將產生更少的“滯后” ,這將通過指數回流和重新繪制來破壞您的布局。

  2. 或多或少同時for循環中的每個子元素(在一個遞歸層)調用setTimeout (及其回調),因此這會限制后代元素的顯示,而不是同級元素。

  3. 除非樹中的每個元素都以display:none開頭,否則將頂級元素設置為display:''將一次性顯示樹。

您確定顯示頂級<div>是導致延遲的原因嗎? 代碼示例可能會幫助社區找到問題的根源。 第一個建議是將更改display的代碼包裝在requestAnimationFrame rAF 上的 MDN

注 1A:我說“指數”是因為您分別顯示每個子元素與一個容器元素,但當然操作數量與后代總數呈線性關系,忽略它們的相對“容器”/“包含”狀態。

注意 1B:此代碼不一定會“顛簸”您的布局; 您正在對布局執行一系列“寫入”操作,如果所有函數調用都可以在一個幀的空間內(~17 毫秒)進行處理,那么現代瀏覽器可能會在幀的末尾自動對這些布局進行批處理,並且我們只談論非節流的兄弟姐妹揭示。 異步節流將允許從代碼的其他部分“讀取”,強制重排,但由於延遲已經是 5 幀的長度,這無關緊要。 關鍵是這段代碼不會減少任何形式的“滯后”。

感謝this-vidor解釋了我擁有的功能的一些問題。 我不知道在我的特定情況下究竟是什么導致了非常奇怪的行為,因為我試圖用 jsbin 上的假數據重現它並且沒有遇到同樣的問題。 我決定為我的特定情況構建一個自定義函數,它看起來像這樣

Messages: function (page) {
    var messageCount = 0;
    var curThrottle = 0;
    page.style.display = '';
    var children = page.children;
    var lastChild = children[children.length - 1];
    var lastChildsChildren = lastChild.children;
    for (var i = 0; i < lastChildsChildren.length; i++) {
        var child = lastChildsChildren[i];
        child.style.display = '';
        var messages = child.children[child.children.length - 1].children;
        for (var j = 0; j < messages.length; j++) {
            if (++messageCount%40 === 0) curThrottle += 30;
            var message = messages[j];
            (function (message) {
                setTimeout(function() {
                    message.style.display = '';
                }, curThrottle);
            })(message);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM