必须显式声明 transition: opacity 0.3s ease,不能用 all;初始状态需同时设置 opacity: 0、visibility: hidden 和 pointer-events: none;js 触发应通过 class 切换而非直接赋值 style.opacity,并在 transitionend 中校验 e.propertyname === 'opacity'。

transition: opacity 必须写全属性名,不能用 all
直接写 transition: all 0.3s 看似省事,但浏览器会把所有可动画属性都纳入过渡范围。如果元素同时有 color、border 或意外触发的 transform 变化,动画就可能抽搐、延迟,甚至根本不动——尤其首次显示时若没设 opacity 初始值,all 根本找不到“从哪开始变”。
必须显式声明:transition: opacity 0.3s ease;,不加属性名等于没写。
初始状态里 opacity 和 visibility 都得手动设
只写 .box { opacity: 0; } 不够。浏览器需要明确“起始状态”,否则 transition 不会启动。
更关键的是,opacity: 0 的元素仍占布局空间、仍响应鼠标事件。所以初始状态应是:
opacity: 0;visibility: hidden;-
pointer-events: none;(避免透明但可点)
淡入时统一改这三项,才能真正实现“视觉出现 + 可交互 + 不占位干扰”。
JS 触发淡入时别直接赋值 style.opacity
常见错误:el.style.opacity = 0; el.style.opacity = 1; —— 浏览器会合并渲染,跳过中间帧,结果就是瞬时切换。
轻量解法是强制重排:el.style.opacity = 0; el.offsetHeight; el.style.opacity = 1;
但更推荐用 class 切换,例如:
- 定义
.show { opacity: 1; visibility: visible; pointer-events: auto; } - JS 中执行
el.classList.add('show'); - 这样样式与逻辑分离,也方便复用和测试
动画结束 ≠ 状态就绪,transitionend 要过滤属性名
transitionend 事件可能被多次触发,比如你同时过渡了 opacity 和 visibility,但 visibility 实际不支持缓动,它只是在时间点“啪”一下生效。
所以监听时必须检查:if (e.propertyName === 'opacity'),否则容易误判动画完成时机。
真正容易被忽略的不是怎么让元素“变出来”,而是“变出来之后,它是不是真的能点、有没有挡住下层内容、布局有没有意外撑开”——这些都得靠 visibility 和 pointer-events 配合控制,单靠 opacity 永远不够。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











