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

设置audio.currentTime后自动重置为0的技术求助

问题分析与解决方案

核心问题原因

  1. 重复绑定loadedmetadata事件:每次调用loadSong都会新增一个loadedmetadata监听,多次触发时逻辑冲突,导致设置被干扰。
  2. 事件覆盖问题:代码同时用addEventListener('loadedmetadata')和audio.onloadedmetadata = function(),后者会直接覆盖前者的绑定,部分逻辑失效。
  3. 媒体未进入可跳转状态:loadedmetadata仅代表元数据加载完成,但媒体可能未缓存足够字节支持跳转,此时设置currentTime大概率会被重置。

修复后的代码

audio = document.querySelector('.audio');
let songIndex;

// 单独定义元数据加载处理函数,方便移除重复监听
function handleMetadataLoaded() {
    console.log('audio.duration: ' + audio.duration);
    if (audio.duration >= 30) {
        // 等待媒体可播放后再设置跳转位置
        audio.addEventListener('canplay', function setSeekPosition() {
            audio.currentTime = 30;
            console.log('CurrentTime: ' + audio.currentTime);
            // 仅执行一次,避免重复触发
            audio.removeEventListener('canplay', setSeekPosition);
        }, { once: true });
    } else {
        console.log('duration < 30');
    }
    // 同步更新时长显示
    songDuration.innerHTML = timeCalc(audio.duration);
}

// 初始化歌曲
fetch(music_default_url)
    .then(response => response.json())
    .then(data => {
        dataLength = data.length;
        songIndex = Math.floor(Math.random() * dataLength);
        loadSong(data[songIndex]);
        console.log('DATA DOWNLOADED');
    })
    .catch(err => console.log(err));

// 加载歌曲逻辑
function loadSong(track) {
    title.innerHTML = track.data.title;
    artist.innerHTML = track.data.artist;
    // 先移除旧的监听,避免重复绑定
    audio.removeEventListener('loadedmetadata', handleMetadataLoaded);
    
    audio.src = "/" + track.data.path.replace(/\\/g, "/");

    // 绑定元数据加载事件,仅执行一次
    audio.addEventListener('loadedmetadata', handleMetadataLoaded, { once: true });

    // 实时更新当前时间显示
    audio.addEventListener('timeupdate', function() {
        currentTimeBlock.innerHTML = timeCalc(audio.currentTime);
    });

    let previewPath = "/" + track.data.coverImage.replace(/\\/g, "/");
    previewImg.style.background = `url("${previewPath}")`;
}

关键修复点

  • 统一事件管理:用命名函数配合removeEventListener避免重复绑定事件,防止逻辑冲突。
  • 等待可播放状态:通过canplay事件确认媒体缓存足够数据后再设置currentTime,确保跳转生效。
  • 实时更新当前时间:原代码直接赋值时audio.currentTime还未加载完成,改为监听timeupdate事件实时同步。
  • 单次事件触发:使用{ once: true }选项让事件仅执行一次,避免冗余逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 09:52:54