CSS过渡被移除场景及切换display后过渡失效问题排查
问题原因
你在fadePageIn回调中执行的样式修改是同步执行的:
on_page.style["display"] = "none"; page_1.style["display"] = ""; // 此时page_1的opacity仍为0 page_1.style["opacity"] = "1";
浏览器会把同一次事件循环内的所有样式修改合并后再执行渲染,相当于浏览器渲染时直接拿到的page_1状态是display:block + opacity:1,没有捕捉到opacity:0的初始状态,过渡动画没有可计算的状态差,所以直接跳转到最终状态,不会触发淡入效果。
修复方案
只需要在设置新页面display为可见后,主动触发一次浏览器重排,让浏览器先记录下当前opacity:0的状态,再修改opacity为1即可,修改后的fadePageIn函数如下:
function fadePageIn() { on_page.style["display"] = "none"; page_1.style["display"] = ""; // 主动读取元素布局属性,触发重排,让浏览器同步当前opacity:0的状态 void page_1.offsetWidth; page_1.style["opacity"] = "1"; on_page.removeEventListener('transitionend', fadePageIn); }
CSS过渡不触发/被中断的常见场景
- 同一渲染帧内同时修改过渡属性的起始值和结束值,浏览器合并样式更新,没有可计算的状态差
- 过渡进行过程中,元素被设置
display: none或者直接从DOM树中移除 - 过渡属性的前后值完全一致,没有发生变更
- 元素的
transition属性被中途修改为none,或者被其他更高优先级的样式覆盖 - 要过渡的CSS属性本身不支持动画(如
display、float、position的枚举值等) - 元素初始为
display: none,首次改为可见状态时直接修改过渡属性,没有先触发重排同步初始状态
内容的提问来源于stack exchange,提问作者TimH
相关产品推荐
相关产品推荐

