如何用JavaScript同步控制SVG中SMIL动画与关联音频的启停
问题核心原因
- 你当前给同一个SVG元素绑定了2个独立的点击事件监听器,二者逻辑没有同步:音频的处理逻辑是切换播放/暂停状态,但动画的点击事件只执行
unpauseAnimations操作,无法触发暂停,导致二者状态错位 - 原有
mouseout事件只暂停了动画,没有同步暂停音频,也会导致二者状态不一致
合并后的完整可运行代码
直接替换你现有的两段<script>块即可:
<script type="text/javascript"> (function () { // 统一获取SVG元素,避免重复查询DOM,兼容原有两种选择逻辑 const svg = document.querySelector(".svg-gears") || document.getElementsByTagName('svg')[0]; let audio = null; // 初始状态暂停SMIL动画,和原有逻辑保持一致 svg.pauseAnimations(); // 统一的点击处理逻辑,同步控制音频和动画状态 function togglePlay() { if (!audio) { // 首次点击初始化音频,同步启动音频和动画 audio = new Audio('https://arteurope.de/files/Vergessen.mp3'); audio.play(); svg.unpauseAnimations(); } else if (audio.paused) { // 音频处于暂停状态时,同步启动二者 audio.play(); svg.unpauseAnimations(); } else { // 音频处于播放状态时,同步暂停二者 audio.pause(); svg.pauseAnimations(); } } // 绑定点击事件 svg.addEventListener('click', togglePlay, false); // 鼠标移出时同步暂停动画和音频 svg.addEventListener("mouseout", function() { svg.pauseAnimations(); if (audio && !audio.paused) { audio.pause(); } }); })(); </script>
修改说明
- 合并了两个独立的脚本块,共享状态变量,从根源上避免逻辑冲突
- 所有状态切换操作都在同一个处理函数内完成,保证音频和动画的启停完全同步
- 鼠标移出事件新增了同步暂停音频的逻辑,避免二者状态不一致
- 保留了原有的DOM选择逻辑,优先匹配带
.svg-gears类的SVG元素,找不到再取页面第一个SVG元素,适配你原有站点的结构
内容的提问来源于stack exchange,提问作者Frank Olsowski
相关产品推荐
相关产品推荐

