[英]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);
}
}
幾個問題。
通過設置display:block
(或display:''
)一次性display:block
頂級<div>
將僅觸發一頁重排和重新繪制,因此與遞歸顯示子項相比,將產生更少的“滯后” ,這將通過指數回流和重新繪制來破壞您的布局。
或多或少同時for
循環中的每個子元素(在一個遞歸層)調用setTimeout
(及其回調),因此這會限制后代元素的顯示,而不是同級元素。
除非樹中的每個元素都以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.