[英]Why doesn't a css transition fire immediately after display change
TL;DR不透明度的 css 轉換不會在顯示更改后立即起作用,但會與setTimeout(.., 100)
一起起作用。 為什么?
我想使一條消息閃爍幾秒鍾,然后淡出。 看起來很基本,對吧?
好吧,這是一個jsfiddle ,但讓我詳細解釋一下。
假設我有一個消息塊
<div id="message" class="message">
Here be dragons
</div>
哪個開始隱藏但不透明
.message {
opacity: 1;
display: none;
}
准備好消息后,我想展示它。
document.getElementById("message").style.display = "block"
現在我想讓消息淡出,所以我在不透明度上添加了一個簡單的過渡。
.flash {
opacity: 0;
transition: opacity 2s ease-out 1s;
}
我申請以下
document.getElementById("message").classList.add("flash")
消息 div 顯示但它保持不可見,因為opacity: 0
立即應用。 此外, transitionend
事件沒有觸發,這讓我覺得由於某種原因根本沒有發生過渡。 很奇怪,對吧?
但是,一旦我添加超時,一切都很好
document.getElementById("message").style.display = "block"
setTimeout(() => (document.getElementById("message").classList.add("flash")), 100)
那行得通,但似乎是一個完全骯臟的黑客。 為什么會這樣?
您可以在jsfiddle上看到這種行為,其中有兩個按鈕被恰當地命名為“工作”和“不工作”;
有兩件事共同導致了這一點:
當項目有display: none
時, opacity
將被忽略(因為不相關)。 因此,當您將display: block
應用於它們時,它們會使用當前值渲染提供的opacity
,而不會產生任何過渡效果。
您應用於style
屬性的更改在繪制(異步)發生時一起應用,因此transition
定義來得太晚了。
首先,確保在實際應用之前在message
CSS 類中設置過渡效果定義。
然后我會建議使用height
而不是display
來獲得相同的效果。 您還需要打開和關閉邊框(通過其寬度):
document.getElementById("working").addEventListener("click", () => { document.getElementById("message").classList.add("flash"); }) // reset document.getElementById("message").addEventListener("transitionend", () => { document.getElementById("message").classList.remove("flash") })
.message { border: solid 0px; background: grey; opacity: 1; transition: opacity 2s ease-out 1s; overflow: hidden; height: 0; }.flash { height: 100%; opacity: 0; border-width: 1px }
<div id="message" class="message"> Here be dragons </div> <button id="working"> Working </button>
為什么它不起作用是因為您同時應用了display:block
和opactiy: 0
。 當您在 css 中設置屬性display
時,它會忽略所有轉換,設置顯示和轉換之間必須有一個事件。 另一種方法是使用visibility:hidden
和visibility:visible
而不是 display 但請注意,這只會隱藏元素並且元素仍然存在於其位置
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.