You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript倒计时归零时Alarm报警音频重复播放问题

问题根因

代码存在两个逻辑缺失,才会导致音频重复播放:

  • 没有给音频播放加触发条件:setInterval会每秒执行一次updateCountdown,如果你直接把audio.play()写在这个函数里,没有绑定「时间归零」的判断,函数每跑一次就会触发一次播放,自然每秒都响
  • 时间归零后没有停止定时器:就算加了归零判断,如果不清除持续运行的定时器,后续每次定时器触发还是会走到播放逻辑,重复触发音频
修复方案
  • 首先保存setInterval返回的定时器ID,方便时间归零时彻底停止循环任务
  • 在updateCountdown的时间计算逻辑里,当时间递减到0时,先清除定时器,再触发音频播放,保证播放逻辑只会执行一次
  • 如果需要报警音持续循环,直接设置音频对象的loop属性即可,不要依赖定时器重复调用播放方法
修复后可直接运行的代码
let time = startingMinutes * 60;
const countdownEl = document.getElementById('Countdown');
// 保存定时器ID用于后续清除
const countdownTimer = setInterval(updateCountdown, 1000);

// 初始化音频
const audio = new Audio();
audio.src = "alarm.mp3";
// 需要报警音循环播放就取消下面这行的注释
// audio.loop = true;

function updateCountdown () {
    const minutes = Math.floor(time / 60);
    let seconds = time % 60;
    // 秒数补0
    seconds = seconds < 10 ? '0' + seconds : seconds;
    countdownEl.innerHTML = `${minutes}:${seconds}`;

    time--;
    // 时间归零判断
    if (time < 0) {
        time = 0;
        // 清除定时器,停止每秒执行的回调
        clearInterval(countdownTimer);
        // 触发报警音,加catch处理浏览器自动播放限制的报错
        audio.play().catch(err => {
            console.warn('音频自动播放被浏览器拦截,请用户先与页面产生交互后再启动倒计时', err);
        });
    }
}
补充说明
  • 现代浏览器默认禁止无用户交互的页面自动播放音频,建议给倒计时加一个启动按钮,用户点击按钮后再开始计时、初始化音频,就能避免播放被拦截的问题
  • 播放逻辑必须放在time < 0的判断分支内部,不要放在分支外,否则还是会被每秒执行的定时器重复触发

内容的提问来源于stack exchange,提问作者Donut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:39:30