jquery实现自定义的audio

最近接到一个古早的项目变更。设计的音乐播放的功能是自定义的样式。对于jquery的项目第一反应是先找插件。然而找了半天没找到。最后只能自己实现。

预期效果

预期实现功能

  • 自定义实现进度条及进度监控
  • 可以手动定位进度
  • 播放(每次只能播放一个,不允许多个同时播放)
  • 暂停

实现方案

1. 进度条

进度条使用<input type="range" />

根据需求,可使用的属性如下:

js 复制代码
<input 
    onchange="playTime(${element.id}, this)" 
    id="progress_${element.id}" 
    value="0" 
    type="range" 
    min="0" 
    max="100" 
    step="0" 
 />

但是原生的样式不符合要求。但是调整样式又需要兼容chrome和firefox。

调整样式参考文档1文档2

最终的样式代码如下:

css 复制代码
[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
    outline: 0;
    background-color: transparent;
    width: 22.125rem;
}
[type="range"]::-webkit-slider-runnable-track {
    height: 4px;
    background: #eee;
}
[type="range"]::-moz-range-track {
    height: 4px;
    background: #eee;
}
[type="range" i]::-webkit-slider-container {
    height: 10px;
    overflow: hidden;
}
[type="range" i]::-moz-range-progress {
    height: 10px;
    overflow: hidden;
}
input[type=range]::-moz-range-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 2px;
    height: 2px;
    border-radius: 50%;
    background-color: #B32B2B;
    border: 1px solid transparent;
    margin-top: -1px;
}
input[type="range"]::-moz-range-progress {
    background-color: #B32B2B;
    height: 4px;
}
[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background-color: #B32B2B;
    border: 1px solid transparent;
    border-image: linear-gradient(#B32B2B,#B32B2B) 0 fill / 0 2 0 0 / 0px 0px 0 2000px;
}

播放

在多个播放器同时存在时,我们需要做到同一个页面同时播放的只有一个

首先渲染页面

js 复制代码
    function musicList(id, index) {
            let str = "";
            musics?.slice(index, index + 10)?.forEach(element => {
                str += `<div>
                        <div class="swiper-img-item">
                                <img src="./images/top.png" />
                                <div>${element.title}</div>
                                <audio class="topAudio" id="top_audio_${element.id}" src=${element.url}  />
                                <img onclick="topPlay(${element.id})" id="top_play_${element.id}" class="second" src="./images/top_play.svg" />
                                <img onclick="topPause(${element.id})" style="display: none;" id="top_pause_${element.id}" class="second" src="./images/top_off.svg" />
                        </div>
                </div>`
            })
            $(`#${id}`).find(".wrapper").append(str);
    }

其次增加方法

js 复制代码
	function play(id) {
		$("audio").each(function() {
			var itemPlayId = $(this).attr("id")?.replace("audio", "play");
			var itemPauseId = $(this).attr("id")?.replace("audio", "pause");
			if ($(this).attr("id") != ("top_audio_"+id)) {			
				$(this).get(0).pause();
				$("#"+itemPauseId).hide();
				$("#"+itemPlayId).show();
			} else {
				$(this).get(0).play();
				$("#"+itemPauseId).show();
				$("#"+itemPlayId).hide();
			}
		})
	}

3. 播放进度监控

通过audio的timeupdate事件监听播放进度,并通过duration获取总的长度。currentTime获取当前长度。

js 复制代码
	$(".musicAudio").each(function() {
		var that = $(this);
		var audio = that.get(0);
		audio.addEventListener("timeupdate", event => {
			var id = that.attr("id").split("_").reverse()[0];
			var curTime = dayjs(audio.currentTime*1000).format("mm:ss");
			var duration = dayjs(audio.duration*1000).format("mm:ss");
			$(`#time_${id}`).html(`${curTime}/${duration}`)
			$(`#progress_${id}`).get(0).value = (audio.currentTime*1000/(audio.duration*1000))*100;			
		})
	})

监听事件图省事挨个添加的。理论上应该搞一个事件委托,在父级进行监听。

相关推荐
互联网搬砖老肖1 小时前
Web 架构之 CDN 加速原理与落地实践
前端·架构
会飞的鱼先生1 小时前
javascript中Cookie、BOM、DOM的使用
前端·javascript·chrome
OpenTiny社区1 小时前
开源之夏·西安电子科技大学站精彩回顾:OpenTiny开源技术下沉校园,点燃高校开发者技术热情
前端·开源
多多*1 小时前
基于rpc框架Dubbo实现的微服务转发实战
java·开发语言·前端·redis·职场和发展·蓝桥杯·safari
灏瀚星空1 小时前
用HTML5 Canvas打造交互式心形粒子动画:从基础到优化实战
前端·html·html5
Jackson__1 小时前
聊一下HTTP 与 HTTPS 的区别,以及HTTPS 的加密方式
前端·面试
好运yoo2 小时前
npm install的原理
前端·npm
Jiaberrr2 小时前
uniapp 安卓 APP 后台持续运行(保活)的尝试办法
android·前端·javascript·uni-app·app·保活
不老刘2 小时前
uniapp+vue3实现CK通信协议(基于jjc-tcpTools)
前端·javascript·uni-app
蓝婷儿2 小时前
第二章支线八 ·CSS终式:Tailwind与原子风暴
前端·css