当前位置:首页 > 文章列表 > 文章 > 前端 > JavaScript Animation.commitStyles 怎样将动画当前位置写入样式

JavaScript Animation.commitStyles 怎样将动画当前位置写入样式

来源:17golang原创 2026-10-27 14:43:05 0浏览 收藏
热门推荐
漫画APP
动画内容聚合,热门资源快捷查看
立即下载

如果一个 Web Animations API 动画结束后还要保留它当前的位移、透明度或其他计算样式,可以调用 animation.commitStyles()。它会把动画当前的计算值写入目标元素的 style 属性;调用没有参数,返回值是 undefined。实际使用时,通常先等待 animation.finished,再提交样式。

最小写法是:创建动画,等待 finished,调用 commitStyles()。如果要兼容仍要求填充模式的旧浏览器,给动画加上 fill: "forwards",提交后再调用 cancel() 清掉持续填充状态。

官方资料:https://developer.mozilla.org/en-US/docs/Web/API/Animation/commitStyles

commitStyles 写入的到底是什么

commitStyles() 操作的是动画目标元素,而不是创建一份新的 DOM 节点。它读取动画当前位置对应的计算样式,并将这些值写入目标元素的 style 属性。这样动画对象不再是唯一的样式来源,元素后续可以像普通内联样式一样继续修改。

const card = document.querySelector('.card');

if (!card) {
  // 目标元素不存在时先停止,避免对 null 创建动画。
  throw new Error('找不到动画目标');
}

const animation = card.animate(
  { transform: ['translateX(0)', 'translateX(160px)'], opacity: [1, 0.7] },
  { duration: 600, easing: 'ease-out' },
);

// 等动画完成后,把当前位置的计算值写进目标元素的 style 属性。
await animation.finished;
animation.commitStyles();

// 提交后仍可像普通内联样式一样继续修改。
card.style.opacity = '1';
Animation 当前计算值通过 commitStyles 写入目标元素 style 属性的静态关系图
图1:Animation.commitStyles() 将动画当前计算值写入目标元素 style 属性的静态关系图,不是运行截图或执行证据。

用 finished 等待动画结束再提交

标题里的“当前位置”并不只指最终关键帧。只要在动画仍运行时调用,提交的就是调用时刻的计算值;如果需求是保存最终状态,最清楚的边界是等待 animation.finished 兑现后再调用。这样调用点和“保存最终结果”的意图一致,也避免在动画尚未到达目标值时提前写入。

async function settlePanel(panel) {
  if (!panel) {
    // 调用方传入空节点时返回一个可识别的错误。
    throw new Error('panel 不能为空');
  }

  const animation = panel.animate(
    { transform: ['translateY(20px)', 'translateY(0)'] },
    { duration: 450, fill: 'none' },
  );

  try {
    // finished 在动画正常完成后兑现,随后再提交最终计算值。
    await animation.finished;
    animation.commitStyles();
  } catch (error) {
    // 动画被取消时不要把未完成的中间状态当成最终样式。
    if (animation.playState !== 'idle') {
      throw error;
    }
  }
}

await settlePanel(document.querySelector('.panel'));

这里的关键顺序是 finished 在前、commitStyles() 在后。方法本身不需要传入属性名或目标元素,因为目标元素和当前动画状态已经保存在 Animation 对象里。

fill: forwards 与 cancel() 怎么配合

在较新的浏览器中,动画结束后不设置 fill 也可以提交样式;但为了照顾仍要求填充模式的旧环境,稳妥写法是使用 fill: "forwards"。提交完成后应调用 cancel(),否则填充动画会一直优先于静态样式,影响元素之后的正常样式更新。

async function commitWithCompatibility(button) {
  if (!button) {
    // 没有目标按钮就不创建动画。
    throw new Error('button 不能为空');
  }

  const animation = button.animate(
    { transform: ['translateX(0)', 'translateX(100px)'] },
    // fill 让旧浏览器在 finished 后仍能读取最终状态。
    { duration: 500, fill: 'forwards' },
  );

  // 先等待最终状态,再把它写入 style 属性。
  await animation.finished;
  animation.commitStyles();

  // 提交完成后取消填充动画,避免它继续压过静态样式。
  animation.cancel();
}

await commitWithCompatibility(document.querySelector('.move-button'));
现代浏览器与旧浏览器兼容写法中 finished、fill、commitStyles 和 cancel 的静态关系对比图
图2:现代浏览器写法与 fill: forwards 兼容写法的静态策略对比图,不是浏览器界面截图。

如果项目只支持已经确认具备新行为的浏览器,可以省略 fill 和后续的 cancel();如果发布范围无法精确控制,保留兼容写法更容易解释,也更不容易留下一个长期填充的动画对象。

调用时机和返回值要怎么判断

这个方法的 API 形状很简单,但调用时机决定了结果:

问题结论写法
需要保存最终状态等待动画完成后提交await animation.finished; animation.commitStyles()
需要保存某个中间位置在指定时刻直接提交animation.commitStyles()
需要兼容旧环境提交前保留填充,提交后取消动画fill: "forwards" + cancel()
想读取方法结果不要期待返回节点或样式对象返回值是 undefined

commitStyles() 不会替你重新播放动画,也不会把动画对象转换成新的 CSS 规则。它只是在调用点把当前计算值落到元素的内联样式上。调用完成后可以继续更新 element.style,也可以根据业务需要重新创建下一段动画。

最后用四个问题选择写法

  • 保存的是最终状态还是中间状态?最终状态先等待 finished,中间状态按时机直接提交。
  • 目标浏览器是否包含仍要求填充模式的旧环境?不确定时使用 fill: "forwards",提交后调用 cancel()。
  • 是否误以为方法需要参数?不需要参数,目标元素和当前值来自 Animation 对象。
  • 是否把返回值当作新样式对象?不应这样做;返回值为 undefined,需要继续修改时直接操作目标元素的 style。

相关问题

commitStyles() 会把动画转成 CSS 规则吗?

不会。它把当前计算值写入目标元素的 style 属性,不会生成新的样式表规则。

为什么调用 commitStyles() 后还要 cancel()?

当动画用了 fill: "forwards" 时,填充状态会继续参与样式优先级。提交后取消动画,可以让已经落地的内联样式接管后续状态。

commitStyles() 有参数或返回值吗?

它没有参数,返回 undefined。方法通过当前 Animation 实例找到目标元素和计算样式。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
JavaScript HTMLSlotElement.assignedElements 怎样读取插槽分配的元素JavaScript HTMLSlotElement.assignedElements 怎样读取插槽分配的元素
上一篇
JavaScript HTMLSlotElement.assignedElements 怎样读取插槽分配的元素
JavaScript Element.getAnimations 怎样收集子树动画对象
下一篇
JavaScript Element.getAnimations 怎样收集子树动画对象
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    735次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    736次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    816次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    776次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    611次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码