如何通过JavaScript动态修改CSS @keyframes关键帧属性?
完全可以实现动态调整动画终点坐标,两种常用实现方案如下:
方案1:直接操作CSSOM修改@keyframes规则
浏览器原生提供了CSS规则操作接口,可以直接定位到目标关键帧修改属性值,不需要重写整段样式。
实现代码:
// 提前计算目标终点坐标,比如获取底部导航栏的位置 const bottomNav = document.querySelector('.bottom-nav'); // 坐标计算逻辑可按需调整,比如减去元素自身高度避免遮挡导航栏 const finalLeft = bottomNav.offsetLeft; const finalTop = bottomNav.offsetTop - 40; // 遍历样式表找到目标关键帧 let targetKeyframes = null; for (const styleSheet of document.styleSheets) { try { for (const rule of styleSheet.cssRules) { if (rule.type === CSSRule.KEYFRAMES_RULE && rule.name === 'move-to-bottom') { targetKeyframes = rule; break; } } } catch (e) { // 跨域引入的样式表无法访问cssRules,直接跳过即可 continue; } } // 修改to帧的坐标值 if (targetKeyframes) { const toFrame = targetKeyframes.findRule('to'); toFrame.style.left = `${finalLeft}px`; toFrame.style.top = `${finalTop}px`; }
注意:如果你的CSS样式是跨域引入的(比如CDN托管的样式),浏览器会出于安全限制禁止访问cssRules接口,这种场景推荐用下面的方案。
方案2:CSS变量传值(推荐)
这是目前兼容性最好、代码最简洁的实现方式,不需要遍历样式表,也不会遇到跨域样式的访问限制。
首先把原有CSS代码稍作修改,把硬编码的终点坐标替换成CSS变量:
<div id="saved-test"></div> <style type="text/css"> #saved-test { width: 40px; height: 40px; background: red; position: fixed; top: 0; left: 0; animation-name: move-to-bottom; animation-duration: 5s; z-index: 1000; /* 定义变量存终点坐标,给默认值兜底 */ --move-end-left: 400px; --move-end-top: 500px; } @keyframes move-to-bottom { to { left: var(--move-end-left); top: var(--move-end-top); } } </style>
JS部分只需要计算完动态坐标后,直接给元素更新CSS变量值即可:
// 计算动态终点坐标 const bottomNav = document.querySelector('.bottom-nav'); const finalLeft = bottomNav.offsetLeft; const finalTop = bottomNav.offsetTop - 40; // 更新元素上的CSS变量 const moveEl = document.getElementById('saved-test'); moveEl.style.setProperty('--move-end-left', `${finalLeft}px`); moveEl.style.setProperty('--move-end-top', `${finalTop}px`);
如果需要在动画运行过程中修改终点、让动画从头按新坐标执行,加三行代码重置动画状态即可:
moveEl.style.animation = 'none'; moveEl.offsetHeight; // 触发浏览器重排,清除原有动画状态 moveEl.style.animation = '';
内容的提问来源于stack exchange,提问作者Andrew Newby
相关产品推荐
相关产品推荐

