宽屏环境下Scheduler恢复100%宽度时transitionend事件提前触发
解决宽屏设备上Scheduler transitionend事件提前触发的问题
看起来你遇到了一个挺常见的浏览器过渡事件坑——宽屏设备下硬件加速或者浏览器的过渡事件触发逻辑差异,导致transitionend在视觉上的过渡还没完成时就触发了,进而让resize操作执行时机不对,事件没法正确归位。下面给你几个实用的解决方案:
1. 精准过滤目标过渡属性
很多时候transitionend会为元素上的每一个过渡属性都触发一次事件(比如如果你的Scheduler同时有width和opacity过渡),可能你捕获到的是其他属性的结束事件,而非width的。所以在回调里一定要判断触发事件的属性:
// 假设scheduler是你的Scheduler元素 scheduler.addEventListener('transitionend', (event) => { // 只处理width属性的过渡结束事件 if (event.propertyName !== 'width') return; // 现在再执行resize操作 scheduler.resize(); });
2. 用requestAnimationFrame兜底
浏览器的transitionend有时候会因为硬件加速的渲染优化,提前触发事件。用requestAnimationFrame可以确保你的resize操作在浏览器下一次重绘前执行,这时候过渡的视觉效果肯定已经完成了:
scheduler.addEventListener('transitionend', (event) => { if (event.propertyName !== 'width') return; requestAnimationFrame(() => { scheduler.resize(); }); });
3. 极端情况用微小延迟
如果上面的方法还不行,可以加一个极短的setTimeout(比如10ms),给浏览器足够的时间完成渲染:
scheduler.addEventListener('transitionend', (event) => { if (event.propertyName !== 'width') return; setTimeout(() => { scheduler.resize(); }, 10); });
调试小技巧
你可以在回调里打印当前元素的实际宽度和触发事件的属性,确认问题根源:
scheduler.addEventListener('transitionend', (event) => { console.log('触发事件的属性:', event.propertyName); console.log('当前Scheduler宽度:', scheduler.offsetWidth); });
这样就能知道是事件真的提前触发,还是resize逻辑本身有问题。
内容的提问来源于stack exchange,提问作者Tyler Dahle
相关产品推荐
相关产品推荐

