如何修复音频播放器暂停时拖动进度条后剩余时间显示异常问题
问题原因
- 核心原因是
HTMLMediaElement的currentTime属性赋值为异步生效,你在mouseup事件里刚给au.currentTime赋值完就立即读取该属性,此时取到的还是赋值前的旧值。如果赋值前音频暂停在0s位置,那au.duration - 旧currentTime就等于总时长,完全符合你遇到的现象。 - 还有两个隐性问题可能会引发其他异常:
mousedown里的paused变量没有加声明关键字,会泄露为全局变量- 每次点击播放按钮如果未加载文件,都会重复给文件选择框绑定
input事件,会导致上传逻辑多次触发
修复方案
直接用已经解析好的进度条值计算剩余时长,不要依赖异步更新的au.currentTime,同时修复上述隐性问题即可。
需要修改的代码片段如下:
- 修改
mouseup事件逻辑
tj.addEventListener("mouseup", ()=>{ tj.removeEventListener("input", imput); // 提前解析好目标进度值,后续直接复用 const targetTime = JSON.parse(tj.value); au.currentTime = targetTime; if(!paused){ au.play(); iv = setInterval(()=>{ ts.value = au.currentTime; tj.value = au.currentTime; tt.value = math("-", [au.duration, au.currentTime]); }, 1); pp.innerText = "⏸️" }else{ pp.innerText = "️▶️"; ts.value = targetTime; // 直接用解析好的目标时间计算,不需要等currentTime异步更新 tt.value = math("-", [au.duration, targetTime]); } });
- 给
paused变量加声明,避免全局污染
tj.addEventListener("mousedown", ()=>{ // 加let声明,防止变量泄露 let paused = au.paused; au.pause(); pp.innerText = "️↔️"; try{ clearInterval(iv); }catch(USLISERROOR){} tj.addEventListener("input", imput); });
- 把文件选择框的监听逻辑移到初始化阶段,避免重复绑定
将原本写在播放按钮点击逻辑里的fi.addEventListener部分,移到文件选择框初始化代码之后,只绑定一次:
fi = document.createElement("input"); fi.type = "file"; // 文件选择监听移到此处,全局只绑定一次 fi.addEventListener("input", ()=>{ fl = fi.files[0]; bt.innerText = "checking file type..."; if(fl.type.startsWith("audio/")){ bt.innerText = "reading file..."; rd = new FileReader(); rd.readAsBinaryString(fl); rd.addEventListener("loadend", ()=>{ au.src = "data:"+fl.type+";base64,"+btoa(rd.result); bt.innerText = "reconstructing audio ..." ts.value = 0; tj.hidden = false; tj.value = 0; sl.disabled = false; ly.disabled = false; sl.placeholder = "input lyrics"; au.addEventListener("canplaythrough", ()=>{ bt.innerText = ""; tj.max = au.duration; tt.value = au.duration; }) }); }else{ bt.innerText = "please input audio only."; fl = null; } });
然后删除原来播放按钮点击逻辑里重复绑定的监听代码,仅保留触发文件选择的逻辑即可:
}else{ bt.innerText = "waiting for input..." fi.click(); // 删除原来此处的fi.addEventListener逻辑 }
内容的提问来源于stack exchange,提问作者TGP1cccul8r
相关产品推荐
相关产品推荐

