如何使用JavaScript获取CSS过渡过程中实时的opacity属性值?
解决方案
CSS原生transition没有提供过渡过程中的进度回调接口,你可以通过以下两种方式实现需求:
方案1:使用requestAnimationFrame轮询读取实时opacity值
这是兼容性最好的实现方式,原理是在过渡启动后逐帧读取元素的计算样式,匹配到目标阈值时触发对应操作,过渡结束后自动停止轮询。
注:你原有代码存在笔误,事件监听的变量名
bnt应为btn,示例代码已修正。
完整代码如下:
var btn = document.querySelector("button"); var par = document.querySelector("#parId"); // 存储requestAnimationFrame的id,用于后续取消轮询 let rafId = null; // 阈值配置,可按需修改回调逻辑 const thresholds = [ { value: 0.6, triggered: false, callback: () => { console.log('opacity达到0.6'); alert('opacity 0.6'); } }, { value: 0.4, triggered: false, callback: () => { console.log('opacity达到0.4'); alert('opacity 0.4'); } }, { value: 0.2, triggered: false, callback: () => { console.log('opacity达到0.2'); alert('opacity 0.2'); } }, ] btn.addEventListener("click", (e) => { par.classList.add("removed"); // 启动进度检查轮询 checkOpacityProgress(); }); par.addEventListener("transitionend", () => { // 过渡结束停止轮询,避免性能损耗 cancelAnimationFrame(rafId); par.remove(); }); function checkOpacityProgress() { // 读取当前实时计算的opacity值 const currentOpacity = parseFloat(getComputedStyle(par).opacity); // 遍历检查是否达到未触发的阈值 thresholds.forEach(item => { if (!item.triggered && currentOpacity <= item.value) { item.callback(); item.triggered = true; } }) // 所有阈值触发后可提前停止轮询 const allTriggered = thresholds.every(item => item.triggered); if (!allTriggered) { rafId = requestAnimationFrame(checkOpacityProgress); } }
#parId { transition: opacity 5s; opacity: 1; /* 显式设置初始opacity,避免取值异常 */ } .removed { opacity: 0; }
注意:
alert会阻塞浏览器主线程,触发时会导致过渡动画暂停,若要保持过渡流畅建议优先使用console输出或非阻塞的自定义提示组件。
方案2:使用Web Animations API实现过渡,自带进度控制
如果不需要兼容IE等老旧浏览器,Web Animations API可以更精准地控制动画进度,无需轮询:
var btn = document.querySelector("button"); var par = document.querySelector("#parId"); btn.addEventListener("click", (e) => { // 用WAAPI创建透明度动画,效果和CSS transition完全一致 const animation = par.animate([ { opacity: 1 }, { opacity: 0 } ], { duration: 5000, easing: 'ease' // 和CSS transition默认缓动规则对齐 }); // 动画逐帧更新回调 animation.onupdate = () => { const currentOpacity = 1 - (animation.currentTime / 5000); // 阈值判断逻辑可按需调整 if (currentOpacity <= 0.6 && currentOpacity > 0.59) { console.log('opacity达到0.6'); } if (currentOpacity <= 0.4 && currentOpacity > 0.39) { console.log('opacity达到0.4'); } if (currentOpacity <= 0.2 && currentOpacity > 0.19) { console.log('opacity达到0.2'); } }; // 动画结束回调,替代transitionend事件 animation.onfinish = () => { par.remove(); }; });
内容的提问来源于stack exchange,提问作者user944513
相关产品推荐
相关产品推荐

