簡體   English   中英

在向DOM添加內容時,我需要等待多長時間(setTimeout)來影響類更改?

[英]How long do I need to wait (setTimeout) to affect a class change when adding something to the DOM?

這是場景...我在DOM中添加一個元素,其初始類具有0不透明度,然后添加一個類來觸發不透明度轉換為1 - 一個漂亮的簡單淡入。 這是代碼的樣子:

.test {
  opacity: 0;
  transition: opacity .5s;
}

.test.show {
  opacity: 1;
}
const el = document.createElement('div')
el.textContent = 'Hello world!'
el.className = 'test' // <div class="test">Hello world!</div>
document.body.appendChild(el)

現在要觸發淡入,我可以簡單地將show類添加到元素:

setTimeout(() => {
  el.classList.add('show')
}, 10)

我正在使用setTimeout,因為如果不這樣做,則會立即添加該類,並且不會出現淡入。 它最初只能在屏幕上看到,沒有過渡。 因此,我歷史上使用了10ms的setTimeout,直到現在才有效。 我遇到了需要將其升級到20ms的情況。 這感覺很臟。 有誰知道是否有安全的使用時間? 我錯過了DOM如何在這里工作的東西嗎? 我知道我需要給瀏覽器時間來弄清楚布局和繪畫(因此是setTimeout),但是需要長時間? 我很欣賞任何見解!

注意:看起來你可以避免添加第二個類來淡入元素,從而避免這個時間問題,請參閱silencedogood的答案 如果這對您有用,那么它似乎比下面的方法更好。

如果由於某種原因對您不起作用,請繼續閱讀... :-)


我不認為你可以使用任何合理,安全的setTimeout值。

相反,我會在追加元素之后使用requestAnimationFrame 在我的實驗中,你需要等到第二個動畫幀,粗略地說:

requestAnimationFrame(function() {
    requestAnimationFrame(function() {
        el.classList.add("show");
    });
});

實例:

 document.getElementById("btn").addEventListener("click", function() { const el = document.createElement('div'); el.textContent = 'Hello world!'; el.className = 'test'; document.body.appendChild(el); requestAnimationFrame(function() { requestAnimationFrame(function() { el.classList.add("show"); }); }); }); 
 .test { opacity: 0; transition: opacity .5s; } .test.show { opacity: 1; } 
 <input type="button" id="btn" value="Click me"> 

我的邏輯是,當你看到第一個動畫幀時,你知道DOM已經使用你的元素進行渲染。 因此,在第二個動畫幀上添加類在邏輯上應該在沒有它的情況下進行渲染,因此觸發轉換。

如果我在第一個動畫幀中執行它,它在Firefox上對我來說不可靠:

 document.getElementById("btn").addEventListener("click", function() { const el = document.createElement('div'); el.textContent = 'Hello world!'; el.className = 'test'; document.body.appendChild(el); requestAnimationFrame(function() { //requestAnimationFrame(function() { el.classList.add("show"); //}); }); }); 
 .test { opacity: 0; transition: opacity .5s; } .test.show { opacity: 1; } 
 <input type="button" id="btn" value="Click me"> 

...這對我來說很有意義,因為它會在第一次呈現元素之前添加類。 (如果我在頁面加載時添加元素,它確實有效,但是當我在上面介紹按鈕時沒有。)

您可以使用純css解決方案,因為您擔心由於任意延遲而導致javascript可能“臟”:

@keyframes fadein {
   from { opacity: 0; }
   to   { opacity: 1; }
}

.test {
   opacity: 0;
   animation: fadein 1s;
   animation-fill-mode: forwards;
}

實例:

 document.getElementById("btn").addEventListener("click", function() { const el = document.createElement('div'); el.textContent = 'Hello world!'; el.className = 'test'; document.body.appendChild(el); }); 
 @keyframes fadein { from { opacity: 0; } to { opacity: 1; } } .test { opacity: 0; animation: fadein 1s; animation-fill-mode: forwards; } 
 <input type="button" id="btn" value="Click me"> 

暫無
暫無

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

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