集成快捷键的单曲音频播放器
<h3>效果</h3><div id="showRes" style="margin: 30px; text-align: center;"></div>
<h3>代码</h3>
<div id="hEdiv"><pre id="hEpre">
<style>
#mboard { width: 420px; height: 40px; background: beige; border-radius: 8px; box-shadow: 2px 2px 4px rgba(0,0,0,.5); display: flex; justify-content: center; align-items: center; gap: 8px; position: relative; }
#mboard img { width: 26px; cursor: pointer; }
#mboard img:hover { filter: drop-shadow(1px 1px 1px rgba(0,0,0,.5)); }
#tMsg1, #tMsg2 { width: 45px; font-size: 13px; text-align: center; }
#volwrap { position: absolute; width: 60px; height: 40px; right: 45px; display: grid; place-items: center; background: none; }
#volwrap:hover #volume { display: inline; }
#btnMute:hover ~ #volwrap > #volume { display: inline; }
#volume { position: absolute; width: 50px; height: 4px; opacity: .75; display: none; }
#prog { --track: gray; --prog: red; --prg: 0%; width: 200px; height: 20px; cursor: pointer; background: linear-gradient(to right, var(--prog) var(--prg), var(--track) 0) no-repeat 0% 50%/100% 2px; }
</style>
<div id="mboard">
<img id="btnPlay" src="https://638183.freep.cn/638183/web/icon/play.svg" title="播放/暂停(Alt+X)" alt="" />
<span id="tMsg1">00:00</span>
<span id="prog"></span>
<span id="tMsg2">00:00</span>
<img id="btnMute" src="https://638183.freep.cn/638183/web/icon/unmuted.svg" title="静音 (Alt+J)" alt="" />
<div id="volwrap"><input id="volume" type="range" min="0" max="1" step="0.1" value="1" /></div>
</div>
<p><audio id="aud" src="https://music.163.com/song/media/outer/url?id=1321297488" autoplay loop></audio></p>
<script>
var lastVolume = 1, muted = false;
var imgAr = [
'https://638183.freep.cn/638183/web/icon/play.svg',
'https://638183.freep.cn/638183/web/icon/pause.svg',
'https://638183.freep.cn/638183/web/icon/unmuted.svg',
'https://638183.freep.cn/638183/web/icon/muted.svg',
];
var setVolume = (val) => Math.min(1, Math.max(0, val));
var setMute = () => {
if(lastVolume === 0) return;
muted = !muted;
muted ? (aud.volume = 0, btnMute.src = imgAr) : (aud.volume = lastVolume, btnMute.src = imgAr);
};
var s2m = (seconds) => {
const secs = Math.floor(seconds || 0);
return `${String(secs/60|0).padStart(2,'0')}:${String(secs%60).padStart(2,'0')}`;
};
var mState = () => {
btnPlay.src = aud.paused ? imgAr : imgAr;
btnPlay.title = (aud.paused ? '播放' : '暂停') + ' (Alt+X)';
};
document.addEventListener('keydown', e => {
if(!e.altKey) return;
switch (e.keyCode) {
case 88:
btnPlay.click();
break;
case 74:
setMute();
break;
case 187: case 107:
aud.volume = setVolume(aud.volume + 0.1);
lastVolume = aud.volume;
break;
case 189: case 109:
aud.volume = setVolume(aud.volume - 0.1);
lastVolume = aud.volume;
break;
default:
return;
}
});
aud.onplaying = aud.onpause = () => mState();
aud.ontimeupdate = () => {
prog.style.setProperty('--prg', aud.currentTime/aud.duration*100 +'%');
tMsg1.innerText = s2m(aud.currentTime);
tMsg2.innerText = s2m(aud.duration);
};
aud.onvolumechange = () => {
btnMute.src = aud.volume === 0 ? imgAr : imgAr;
volume.value = aud.volume;
}
btnPlay.onclick = () => aud.paused ? aud.play() : aud.pause();
btnMute.onclick = () => setMute();
volume.onchange = () => aud.volume = lastVolume = volume.value;
prog.onclick = (e) => aud.currentTime = e.offsetX * aud.duration / prog.offsetWidth;
prog.onmousemove = (e) => prog.title = s2m(e.offsetX * aud.duration / prog.offsetWidth);
volwrap.onmouseover = () => volwrap.title = '音量 : ' + volume.value + ' (Alt++/-)'
</script>
</pre></div>
<script type="module">
import hlight from 'https://638183.freep.cn/638183/web/mod/helight.js';
hlight.hl(hEdiv, hEpre);
var runCodes = (str,target) => {
let reg = /(<script(.*?)>)(.|\n)*?(<\/script>)/g;
let js_str, html_str;
if(str.match(reg) !== null) {
js_str = str.match(reg);
html_str = str.replace(js_str, '').trim();
js_str = js_str.replace(/<[\/]{0,1}script[^>]*>/g,'').trim();
} else {
js_str = '';
html_str = str.trim();
}
target.innerHTML = html_str;
let myfunc = new Function(js_str);
myfunc();
};
runCodes(hEpre.innerText, showRes);
</script> 界面可以:
一、修改 #mboard 相关属性加以修饰。若主元素宽度改变,应相应修改 #prog 的 width 属性值;
二、按钮图片可以更改,若更改,一是相应改变两个 img 的 src 属性值,二是按顺序改变 js 代码中的 imgAr 存放的图片地址;
三、音量滑杆使用的是 input type 做成,不太好看,可以考虑:一是使用CSS美化,代码量相对较大、兼容性不太保证,二是使用 HTML 标签仿进度条的做法,js 需要多加点代码。 创新之作,讲解精彩,谢谢老师无私分享{:4_191:} 谢谢老师辛苦!{:4_190:} 黑黑用这样的播放框把前面讲的调整都加进去了呢,真好,可以自己去点播放框里的标识,不用自己去找键盘上的对应键了{:4_199:} 音量调整变成竖直的,放在静音符号上面多好,这样就不会对播放时间有遮挡了{:4_173:} 马黑黑 发表于 2025-2-21 12:31
界面可以:
一、修改 #mboard 相关属性加以修饰。若主元素宽度改变,应相应修改 #prog 的 width 属性值 ...
这滑动杆挺好的,非常明确呢{:4_187:} 红影 发表于 2025-2-21 16:51
这滑动杆挺好的,非常明确呢
这是大致模仿了仿 audio 界面上的样式 红影 发表于 2025-2-21 16:49
音量调整变成竖直的,放在静音符号上面多好,这样就不会对播放时间有遮挡了
这个无关紧要的,调整完了它就会消失。这个做法是原生 audio 标签界面在这个细节上的处理方式,我觉得还是挺好的,就大致模仿了一下。竖着的太突兀。 红影 发表于 2025-2-21 16:45
黑黑用这样的播放框把前面讲的调整都加进去了呢,真好,可以自己去点播放框里的标识,不用自己去找键盘上的 ...
快捷键不是每个人都会习惯,不过快捷键是非常有意义的,这个就是尝试加入了快捷键,同时一改过去没有静音、音量调节的省事做法,都加上了。如果针对多曲播放,还应有前一首、下一首和单曲循环、多曲循环等功能。 杨帆 发表于 2025-2-21 13:32
创新之作,讲解精彩,谢谢老师无私分享
{:4_191:} 梦江南 发表于 2025-2-21 15:43
谢谢老师辛苦!
感谢支持 这一版四键控制更完美啦,可以各种自定义~~
目前看篇幅跟一个贴子差不多。
这以后是不是都会封装起来的呢。。{:4_173:} 这播放器比较经典,看代码真是精工细作,一点点描画出来。。。功能还比之前的更加齐全。。
白老师真帅。。{:4_173:} 花飞飞 发表于 2025-2-21 18:46
这播放器比较经典,看代码真是精工细作,一点点描画出来。。。功能还比之前的更加齐全。。
白老师真帅。。 ...
其实也就是加了快捷键、静音和音量控制 花飞飞 发表于 2025-2-21 18:43
这一版四键控制更完美啦,可以各种自定义~~
目前看篇幅跟一个贴子差不多。
这以后是不是都会封装起来的呢 ...
封装与否还看它成熟里木有,以及有木有必要 即学习了电脑键盘的作用,又学习代码受益匪浅,向老师学习! 亚伦影音工作室 发表于 2025-2-21 21:58
即学习了电脑键盘的作用,又学习代码受益匪浅,向老师学习!
{:4_191:} 马黑黑 发表于 2025-2-21 18:00
这是大致模仿了仿 audio 界面上的样式
这个播放框的功能十分齐全,厉害了{:4_187:}{:4_199:} 马黑黑 发表于 2025-2-21 18:02
这个无关紧要的,调整完了它就会消失。这个做法是原生 audio 标签界面在这个细节上的处理方式,我觉得还 ...
也是,用完就消失了,而且还设置了透明度,倒也无妨{:4_204:}