是否可自定义CSS transition,监听样式变更并替换为自定义动画?
实现方案
方案1:拦截样式修改逻辑(可控性最高)
如果所有样式变更都是通过JS触发,可以直接封装样式修改入口,在修改前做拦截处理:
- 先通过
getComputedStyle(element).transition获取元素原有过渡配置,确认要修改的属性是否在过渡规则内 - 临时给元素设置
transition: none,或者添加带transition: none !important规则的临时类,阻止默认过渡触发 - 必须执行一次强制重排操作(比如读取
el.offsetWidth),确保禁用过渡的配置被浏览器生效 - 执行自定义动画逻辑,动画完成后再恢复元素原有的transition配置即可
参考代码:
const modifyStyleWithCustomAnim = (el, styleKey, targetVal, customAnim) => { // 保存原有过渡配置 const originTransition = el.style.transition // 禁用默认过渡 el.style.transition = 'none' // 强制重排,确保配置生效 void el.offsetWidth // 执行自定义动画 customAnim(el, styleKey, targetVal, () => { // 动画结束后恢复原有过渡配置 el.style.transition = originTransition }) }
方案2:监听过渡事件拦截(适配非JS触发的样式变更)
如果样式变更来自CSS类切换、伪类触发(比如:hover)等非直接JS修改的场景,可以监听元素的transitionrun事件,该事件会在过渡动画正式开始前触发:
- 给目标元素绑定
transitionrun事件监听 - 事件触发后,判断当前触发过渡的属性是否为需要拦截的属性
- 立刻将目标属性重置为过渡前的数值,同时禁用元素过渡配置,阻止默认过渡执行
- 强制重排后执行自定义动画逻辑即可
参考代码:
const el = document.querySelector('.target') el.addEventListener('transitionrun', (e) => { // 按需指定要拦截的属性,不需要全量拦截可删除该判断 if (e.propertyName !== 'width') return // 获取过渡前的属性值 const originVal = getComputedStyle(el)[e.propertyName] // 禁用默认过渡 el.style.transition = 'none' // 重置属性,终止默认过渡 el.style[e.propertyName] = originVal // 强制重排生效 void el.offsetWidth // 此处执行自定义动画逻辑 customAnim(el, e.propertyName, targetVal) })
注意:如果需要拦截所有属性的过渡,删除
propertyName判断即可。
内容的提问来源于stack exchange,提问作者Dest1n1
相关产品推荐
相关产品推荐

