使用HTML+CSS+JS做一个音乐播放器

2021-03-01 20:25

阅读:555

YPE html>

标签:charset   自动   防止   pre   substr   结果   设置   bottom   ogre   

一、观前说明:
1.本人为新手,很多地方可能写得不好,欢迎指正。

2.本人仍在学习CSS中,在本篇中若有写得不好的地方,欢迎指正。

3.本人尚未系统性的学习过JS(还没学到),在这里用到的JS全是靠以前学其他语言积累下的基础,因此在很多地方也会写得不够好,欢迎指正。

4.因HTML部分和CSS部分较为简单,本篇文章会更注重于讲JS部分,其中一些说明我会写在代码里面,我认为这比我写在外面更好理解。

5.我是将整个播放器写完了才写的这篇文章,所以你们在看代码的时候,会看到一些提前写了的代码,比如播放暂停还没讲到修改时间间距,但在代码处已经有了。

二、最终效果

2.1、包含功能

1.播放暂停

2.歌词动画,显示当前歌词

3.拖拽歌词,调整歌词进度

4.进度条调整歌词进度

5.音量控制

2.2、图片展示
技术图片

三、现在开始

1.搭建基础框架

框架图:
技术图片

按照框架图,搭建框架:

其中歌词是后面由JS创建的,因此只需要有一个div包住就行







音乐播放器
韩安旭 - 不在

专辑:

歌手:

00:00
00:00/00:00
100

2.CSS美化

2.1清除所有边距已经禁止选择

* {
    margin: 0;
    padding: 0;
    user-select: none;
}
 
h1 {
    font-weight: 500;
}

a {
    color: #000;
    text-decoration: none;
}

2.2设置背景样式(大盒子)

/* 背景样式,相当于body */
.background {
    width: 100vw;
    height: 100vh;
    background-color: #fff;
}
 
/* 上半部分样式,即包含封面以及歌词的盒子 */
.music-background {
    width: 1000px;
    height: calc(100vh - 200px);
    margin: 0 auto;
    overflow: hidden;
}
 
/* 图片盒子 */
.img-back {
    width: 300px;
    padding: 0 50px;
    margin-top: 150px;
    margin-right: 50px;
    overflow: hidden;
    float: left;
}
 
/* 歌词盒子 */
.lyrics-back {
    width: 550px;
    height: 100%;
    overflow: hidden;
    float: left;
}
 
/* 歌曲信息盒子 */
.div-title {
    width: 100%;
    height: 100px;
    margin-top: 150px;
}
 
/* 控制区域盒子 */
.control-back {
    width: 100vw;
    height: 80px;
    bottom: 0;
    position: absolute;
    background-color: rgba(255, 255, 255, 0.8);
}

2.3设置图片、字体样式

只是简简单单的调整大小边距等,甚至在歌曲信息中的文字段落标签我都没有设置字体大小,事实上这并不是一种好的习惯

.img-back img {
    width: 300px;
    height: 300px;
    border-radius: 20px;
}
 
.div-title h1 {
    width: 100%;
    height: 50px;
}

.div-title p {
    height: 50px;
    display: inline-block;
    color: rgba(0, 0, 0, 0.5);
}

.div-title span {
    color: #000;
}
 
.div-lyrics p {
    font-size: 15px;
    line-height: 34px;
}

2.4设置控制按钮、进度条、音量控制样式

这里我的控制按钮用的都是a标签,因此需要将a标签修改为行内块标签inline-block

其中".lyrics-time"是拖拽歌词时显示的调整进度的按钮,因此在默认状态下需要隐藏

.lyrics-time a {
    display: inline-block;
    position: absolute;
    display: none;
}

.goto {
    width: 20px;
    height: 20px;
    margin: 7px 15px;
    background: url(../img/play.png) no-repeat;
    background-position: 50% 50%;
    background-size: 20px;
}

.goto-time {
    width: 50px;
    height: 34px;
    margin-left: 550px;
    font-size: 13px;
    line-height: 34px;
    text-align: center;
    position: absolute;
    color: #5192fe;
}
 
/* 进度条 */
.progress-bar {
    width: calc(100vw - 100px);
    margin: 5px 0;
    padding: 5px 0;
    cursor: pointer;
    float: left;
}

/* 当前播放进度 */
.progress-now {
    width: 0;
    height: 1px;
    margin-top: -1px;
    background-color: #5192fe;
}

/* 总播放进度 */
.progress-all {
    width: 100%;
    height: 1px;
    background-color: #dee2e6;
}

/* 播放进度 文本 */
.time {
    display: inline-block;
    width: 90px;
    height: 21px;
    margin-left: 5px;
    text-align: center;
    color: rgba(128, 130, 133, 0.8);
    cursor: default;
    overflow: hidden;
}

/* 控制按钮 */
.control {
    width: 100%;
    height: 30px;
    margin-top: 19px;
}

.control a {
    margin: 0 5px;
    display: inline-block;
}

.control a:hover {
    opacity: 50%;
}

.control-btn {
    width: 130px;
    height: 30px;
    margin: 0 auto;
}

/* 上一首 */
.up {
    width: 30px;
    height: 30px;
    background: url(../img/up.png) no-repeat;
    background-size: 20px;
    background-position: 50% 50%;
}

/* 暂停播放 */
.play-pause {
    width: 30px;
    height: 30px;
    background: url(../img/play.png) no-repeat;
    background-size: 30px;
    background-position: 50% 50%;
}

/* 下一首 */
.down {
    width: 30px;
    height: 30px;
    background: url(../img/down.png) no-repeat;
    background-size: 20px;
    background-position: 50% 50%;
}

/* 右侧控制按钮 */
.control-right {
    /* width: 180px; */
    height: 30px;
    margin-left: calc(50vw + 150px);
    margin-top: -30px;
    display: flex;
    align-items: center;
}

/* 播放模式 */
.mode {
    width: 30px;
    height: 30px;
    background: url(../img/sequence.png) no-repeat;
    background-size: 20px;
    background-position: left 50%;
    cursor: pointer;
}

/* 声音控制 */
.volume {
    width: 30px;
    height: 30px;
    background: url(../img/volume.png) no-repeat;
    background-size: 20px;
    background-position: left 50%;
    cursor: pointer;
}

.volume-back {
    padding: 5px 0;
    cursor: pointer;
}

.volume-all {
    width: 100px;
    height: 2px;
    background-color: #e5e5e5;
}

.volume-now {
    width: 100px;
    height: 2px;
    margin-top: -2px;
    max-width: 100px;
    background-color: #5192fe;
}

.volume-text {
    margin-left: 10px;
    font-size: 14px;
}

3.JS部分

3.1首先是声明一些变量、数组等,因为这一部分是要多处使用的,因此在最开头就声明了

var myAduio = document.getElementsByTagName(‘audio‘)[0];
var divLyrics = document.getElementsByClassName(‘div-lyrics‘)[0];
var divTitle = document.getElementsByClassName(‘div-title‘)[0];
var lyricsTime = document.getElementsByClassName(‘lyrics-time‘)[0];
var lyricsTime_a = lyricsTime.getElementsByTagName(‘a‘);
var progressTime = document.getElementsByClassName(‘time‘)[0];
var nowLine = 0;
var lyricsMove = false;
var playState = false;
var lyrics, lyricsStyle, lyricsFirst, rollT;
var timeArray1 = new Array();
var timeArray2 = new Array();
var timeInterval = new Array();

这里面分别是

audio控件,播放音乐用的;

歌词div,到时候要在这里面创建歌词

歌曲信息div,也是在这里面修改歌曲信息的内容

拖拽歌词调整进度的div "lyricsTime"以及里面的按钮 "lyricsTime_a"

进度条右侧的时间"progressTime"

当前播放行"nowLine"

拖拽状态"lyricsMove"

播放状态"playState"

所有歌词的p标签"lyrics",第一行歌词的样式"lyricsStyle",第一行歌词的p标签"lyricsFirst",歌词滚动的计时器"rollT"

以秒数记录每一行歌词所在时间的数组"timeArray1"以及以分钟:秒数的星石记录每一行歌词所在时间的数组"timeArray2",用两种方式记录时间的原因是后面需要以这两种形式交叉使用,也可以只记录一种,在使用到另一种的时候将其算出来,但我感觉直接记录两种会更方便

记录每一行歌词时间间距的数组"timeInterval"

3.2页面加载完毕后就需要执行的方法

window.onload = function () {
	initialLyrics();
	lyricsStyle = getComputedStyle(lyricsFirst, null);
	setLyrics(0);
	setMouseEvent();
	setTimeText();
};

3.3初始化歌词(创建歌词并存储一些信息)

sp、ar、ti分别为专辑、艺术家、歌名

function initialLyrics() {
    let sp = divTitle.getElementsByTagName(‘span‘)[0];
    let ar = divTitle.getElementsByTagName(‘span‘)[1];
    let ti = divTitle.getElementsByTagName(‘h1‘)[0];
    let lyricsData, timeString;
    let lyricsArray = new Array();
    // 清除数组,先清除数组可以保证每一次存储的信息无误
    timeArray1.splice(0, timeArray1.length);
    timeArray2.splice(0, timeArray2.length);
    lyricsArray.splice(0, lyricsArray.length);
    // 按相同格式放入歌词更换歌曲即可达到相同效果
    lyricsData =
        ‘[ar]韩安旭\n[ti]不在\n[sp]不在\n[00:00.74]韩安旭 - 不在\n[00:01.76]词:尤雅琪\n[00:02.76]曲:胜屿\n[00:15.62]我累了就紧紧锁住情绪\n[00:18.11]不再放任它堆积\n[00:22.14]我痛了就静静屏住呼吸\n[00:26.02]不给想念留余地\n[00:28.88]只是下雨时会委屈\n[00:32.80]只是想起你会哭泣\n[00:36.77]没关系 真没关系\n[00:44.28]我终于学会一个人弹琴\n[00:47.12]只是弹琴没有你\n[00:49.29]我终于学会一个人做梦\n[00:54.85]只是做梦没有你\n[00:57.73]我依旧像从前粗心\n[01:01.09]时常会忘记星期几\n[01:05.00]却始终忘不掉你看我的眼睛\n[01:11.71]穿过了熙攘的人海\n[01:15.11]想找谁能把你取代\n[01:19.62]复制你曾给过我的\n[01:21.44]那种宠爱\n[01:26.32]掏空了回忆的脑海\n[01:30.75]寂寞却狠狠扑过来\n[01:33.69]措手不及 无法躲开\n[01:41.52]我承认是我太依赖\n[01:44.92]像个不懂事的小孩\n[01:48.35]挥霍掉我们的未来\n[01:51.22]才醒过来\n[01:55.15]我承认后悔了伤害\n[01:59.06]抛开你的好我的坏\n[02:02.14]直到如今学会忍耐 你不在\n[02:26.95]我终于学会一个人弹琴\n[02:29.33]只是弹琴没有你\n[02:33.26]我终于学会一个人做梦\n[02:36.64]只是做梦没有你\n[02:39.53]我依旧像从前粗心\n[02:42.90]时常会忘记星期几\n[02:46.82]却始终忘不掉你看我的眼睛\n[02:53.62]穿过了熙攘的人海\n[02:57.09]想找谁能把你取代\n[03:00.98]复制你曾给过我的\n[03:05.43]那种宠爱\n[03:08.25]掏空了回忆的脑海\n[03:11.67]寂寞却狠狠扑过来\n[03:15.56]措手不及 无法躲开\n[03:22.49]我承认是我太依赖\n[03:26.37]像个不懂事的小孩\n[03:30.38]挥霍掉我们的未来\n[03:33.80]才醒过来\n[03:37.81]我承认后悔了伤害\n[03:41.29]抛开你的好我的坏\n[03:44.73]直到如今学会忍耐 你不在‘;
    // 文本.split(‘分隔符‘),用于分割文本
    lyricsArray = lyricsData.split(‘\n‘);
    // 添加歌曲信息
    ar.innerText = lyricsArray[0].split(‘]‘)[1];
    ti.innerText = lyricsArray[1].split(‘]‘)[1];
    sp.innerText = lyricsArray[2].split(‘]‘)[1];
    // 添加歌词
    for (var i = 3; i ‘ +
                lyricsArray[i].split(‘]‘)[1] +
                ‘‘;
        } else {
            divLyrics.innerHTML +=
                ‘

‘ + lyricsArray[i].split(‘]‘)[1] + ‘

‘; } } // 获取后续需要使用的变量 lyricsFirst = divLyrics.getElementsByTagName(‘p‘)[0]; lyrics = divLyrics.getElementsByTagName(‘p‘); // 计算每局歌词所在的秒数 timeArray1.push(0); for (var i = 0; i

歌词初始化完后,整个页面就可以正常显示了,接下来先写控制播放暂停的功能

3.3播放暂停

// 设置播放状态
function setPlay(state) {
	var play_pause = document.getElementsByClassName(‘play-pause‘)[0];
	if (state == null) {
		// 如果歌曲为暂停状态,那么获取到的state则为true,将state设置为true我们就播放
		state = myAduio.paused;
	}
	// 清除计时器,不然会出现多个计时器同时进行
	clearTimeout(rollT);
	if (state == true) {
		myAduio.play();
		play_pause.style.backgroundImage = ‘url(../img/pause.png)‘;
		playState = true;
		// 开始播放的同时,同时开始设置时间进度文本,歌词滚动以及进度条位置
		setTimeText();
		lyricsRoll();
		setProgress();
	} else {
		myAduio.pause();
		play_pause.style.backgroundImage = ‘url(../img/play.png)‘;
		playState = false;
		// 暂停后重新修改计时器时间,这里后面会详细讲
		timeInterval[nowLine] = timeArray1[nowLine + 1] - myAduio.currentTime;
	}
}

3.4设置时间进度文本

// 设置进度文本
function setTimeText() {
	var nowTime = myAduio.currentTime;
	var allTime = myAduio.duration;
	// 计算时间,若为个位数,补0
	if (Math.floor(nowTime % 60) 

3.5设置进度条位置

// 设置进度条进度
function setProgress() {
	let progress_now = document.getElementsByClassName(‘progress-now‘)[0];
	let progress_bar = document.getElementsByClassName(‘progress-bar‘)[0];
	let progress = Math.floor(
		(myAduio.currentTime / myAduio.duration) * progress_bar.clientWidth
	);
	progress_now.style.width = progress + ‘px‘;
	if (myAduio.paused == false) {
		setTimeout(setProgress, 100);
	}
}

到这里,除了歌词滚动、调整进度等,一个最简单的音乐播放器就已经完成了

3.6设置歌词位置

// 设置歌词位置
function setLyrics(line) {
	// 将当前歌词高亮,其余歌词都改为黑色
	for (let i = 0; i 

设置歌词写好了,我们现在就需要考虑如何让歌词滚动起来,即让歌词自动到达当前行的位置

我想到的方法有两种

第一种方法是根据每句歌词之间的时间间隔,每过一个间隔,就触发一次方法,我这里用的就是这种方法;

第二种方法是每过很短的一段时间,就触发一次方法,就跟进度条类似;

我观察过酷狗以及QQ音乐,其中酷狗用的应该就是第一种方法,是过一个间隔触发一次的,而QQ音乐则是用的第二种方法。

我个人认为第二种方法写起来更简单,但是需要的性能更高,但是进度条、以及时间进度文本是必须使用第二种方法的(至少我想不到其他的),那么如果将进度条、时间进度文本、歌词滚动这三个方法放在一个计时器中调用,而不是像我这样分开三个计时器,哪一种是更优的方法就不得而知了,欢迎各位大佬给出自己的看法。

那么我们这里用第一种方法,首先我们先分析一下需要记录的内容(其实前面已经记录了,只是在这里才说)

第一个是要记录歌词,这个不需要多的解释,显示用的

第二个需要记录时间间隔,这个是用来设置计时器的

第三个需要记录每一行歌词所在的时间,分两个记录,一个按秒数记录,用来拖拽歌词时调整进度;另一个按分:秒记录,用于拖拽歌词时显示时间;两个数组可只记录一个,用到另一个的时候算出来就好,我为了方便就记录了两个

前面三个都是要用数组记录,第四个则是非数组,用于记录当前歌词到了哪一行,在歌词滚动中,歌词回弹等地方都会用到。

需要记录的东西我们分析完了,那么接下来在画一个逻辑图来分析计时器要如何设置,即歌词滚动要如何实现

技术图片

分析完毕,那么继续

3.7歌词滚动

// 歌词滚动
// 歌词滚动的方法只需要按照时间间隔设置计时器即可
function lyricsRoll() {
	rollT = setTimeout(function () {
		if (nowLine 

到这里,播放器的歌词滚动部分已经写好了,但现在的播放器只能播放暂停,看到歌词在哪,不能调整进度等,接下来我们就来解决这个问题

3.8歌词拖拽、音量控制、调整进度

function setMouseEvent() {
	// 歌词拖拽
	let lyrics_Y, line;
	// 此处是调整歌词位置,以及计算用户将歌词拖拽到了哪一行
	divLyrics.onmousedown = function (e) {
		if (lyricsMove == false) {
			lyricsTime_a[0].style.display = lyricsTime_a[1].style.display = lyricsTime.style.display =
				‘block‘;
			lyricsMove = true;
		}
		lyrics_Y = parseInt(lyricsStyle.marginTop);
		document.onmousemove = function (event) {
			lyricsFirst.style.marginTop =
				event.clientY - (e.clientY - lyrics_Y) + ‘px‘;
			line = Math.floor(-(parseInt(lyricsStyle.marginTop) - 170) / 34);
			if (line  lyrics.length - 1) {
				line = lyrics.length - 1;
			}
			lyricsTime_a[1].innerText = timeArray2[line];
		};
		document.onmouseup = function () {
			// Y1的作用是判断用户是否仍处于拖拽状态,若一秒后歌词位置仍等于Y1,则判断为非拖拽状态,但这样写有一个bug就是如果只是按住鼠标不进行拖拽,则也会判断为非拖拽状态,暂时想不到解决方法
			var lyrics_Y1 = parseInt(lyricsStyle.marginTop);
			setTimeout(function () {
				if (parseInt(lyricsStyle.marginTop) == lyrics_Y1) {
					lyricsMove = false;
					setLyrics(nowLine);
					lyricsTime_a[0].style.display = lyricsTime_a[1].style.display = lyricsTime.style.display =
						‘none‘;
				}
			}, 1000);
			// 清除鼠标移动方法的同时也一定要清除鼠标弹起方法,不然每次点击页面都会调用这个方法
			document.onmousemove = null;
			document.onmouseup = null;
		};
		// 防止选中文字
		return false;
	};

	// 音量控制
	// 音量控制没什么好说的,需要注意的是volume的音量是从0-1,所以在设置音量时要将其除以100
	let volume_now = document.getElementsByClassName(‘volume-now‘)[0];
	let volume_back = document.getElementsByClassName(‘volume-back‘)[0];
	let volume_text = document.getElementsByClassName(‘volume-text‘)[0];
	let volume_a = document.getElementsByClassName(‘volume‘)[0];
	volume_back.onmousedown = function (e) {
		volume_now.style.width = e.offsetX + ‘px‘;
		myAduio.volume = e.offsetX / 100;
		volume_text.innerText = volume_now.clientWidth;
		volume_back.onmousemove = function (ev) {
			let volume = ev.offsetX;
			if (volume > 100) {
				volume = 100;
			}
			volume_now.style.width = volume + ‘px‘;
			myAduio.volume = volume / 100;
			volume_text.innerText = volume_now.clientWidth;
		};
		document.onmouseup = function () {
			// 如果音量为0,更换静音图片,否则更换非静音图片
			if (myAduio.volume == 0) {
				volume_a.style.backgroundImage = ‘url(../img/mute.png)‘;
			} else {
				volume_a.style.backgroundImage = ‘url(../img/volume.png)‘;
			}
			volume_back.onmousemove = null;
			document.onmouseup = null;
		};
		return false;
	};

	// 进度控制
	// 进度控制跟音量控制一样,只需要注意算法就好
	// 从之前的设置进度条进度我们可用知道,进度条的宽度=当前播放进度/歌曲总时长*进度条总长
	// 所以   当前播放进度=进度条宽度/进度条总长*歌曲总时长
	let progress_now = document.getElementsByClassName(‘progress-now‘)[0];
	let progress_bar = document.getElementsByClassName(‘progress-bar‘)[0];
	progress_bar.onmousedown = function (e) {
		progress_now.style.width = e.offsetX + ‘px‘;
		myAduio.pause();
		myAduio.currentTime =
			(e.offsetX * myAduio.duration) / progress_bar.clientWidth;
		setTimeText();
		progress_bar.onmousemove = function (ev) {
			let progress = ev.offsetX;
			if (progress > progress_bar.clientWidth) {
				progress = progress_bar.clientWidth;
			}
			progress_now.style.width = progress + ‘px‘;
			myAduio.currentTime =
				(progress * myAduio.duration) / progress_bar.clientWidth;
			setTimeText();
		};
		document.onmouseup = function () {
			myAduio.play();
			for (var i = 0; i 

3.9设置静音

这个比较简单,就不说了

// 设置静音
function setMuted() {
	let volume_now = document.getElementsByClassName(‘volume-now‘)[0];
	let volume_text = document.getElementsByClassName(‘volume-text‘)[0];
	let volume_a = document.getElementsByClassName(‘volume‘)[0];
	if (myAduio.muted == true) {
		myAduio.muted = false;
		volume_a.style.backgroundImage = ‘url(../img/volume.png)‘;
		volume_now.style.width = myAduio.volume * 100 + ‘px‘;
		volume_text.innerText = myAduio.volume * 100;
	} else {
		myAduio.muted = true;
		volume_a.style.backgroundImage = ‘url(../img/mute.png)‘;
		volume_now.style.width = ‘0‘;
		volume_text.innerText = ‘0‘;
	}
}

到这里,我们的整个播放器就已经全部完成了

以下是完整代码

HTML




	





音乐播放器
韩安旭 - 不在

专辑:

歌手:

00:00
00:00/00:00
100

CSS

* {
	margin: 0;
	padding: 0;
	user-select: none;
}

h1 {
	font-weight: 500;
}

a {
	color: #000;
	text-decoration: none;
}

/* 背景板 */
.background {
	width: 100vw;
	height: 100vh;
	background-color: #fff;
}

/* 歌词封面背景 */
.music-background {
	width: 1000px;
	height: calc(100vh - 200px);
	margin: 0 auto;
	overflow: hidden;
}

/* 封面背景 */
.img-back {
	width: 300px;
	padding: 0 50px;
	margin-top: 150px;
	margin-right: 50px;
	overflow: hidden;
	float: left;
}

.img-back img {
	width: 300px;
	height: 300px;
	border-radius: 20px;
}

/* 歌词背景 */
.lyrics-back {
	width: 550px;
	height: 100%;
	overflow: hidden;
	float: left;
}

/* 歌曲信息 */
.div-title {
	width: 100%;
	height: 100px;
	margin-top: 150px;
}

.div-title h1 {
	width: 100%;
	height: 50px;
}

.div-title p {
	height: 50px;
	display: inline-block;
	color: rgba(0, 0, 0, 0.5);
}

.div-title span {
	color: #000;
}

.div-lyrics {
	height: calc(100vh - 450px);
	overflow: hidden;
	position: relative;
}

.div-lyrics p {
	font-size: 15px;
	line-height: 34px;
}

/* 歌词进度 */
.lyrics-time {
	width: 650px;
	height: 34px;
	margin-top: 136px;
	margin-left: -50px;
	position: absolute;
	display: none;
}

.lyrics-time a {
	display: inline-block;
	position: absolute;
	display: none;
}

.goto {
	width: 20px;
	height: 20px;
	margin: 7px 15px;
	background: url(../img/play.png) no-repeat;
	background-position: 50% 50%;
	background-size: 20px;
}

.goto-time {
	width: 50px;
	height: 34px;
	margin-left: 550px;
	font-size: 13px;
	line-height: 34px;
	text-align: center;
	position: absolute;
	color: #5192fe;
}

/* 控制背景 */
.control-back {
	width: 100vw;
	height: 80px;
	bottom: 0;
	position: absolute;
	background-color: rgba(255, 255, 255, 0.8);
}

/* 进度条 */
.progress-bar {
	width: calc(100vw - 100px);
	margin: 5px 0;
	padding: 5px 0;
	cursor: pointer;
	float: left;
}

/* 当前播放进度 */
.progress-now {
	width: 0;
	height: 1px;
	margin-top: -1px;
	background-color: #5192fe;
}

/* 总播放进度 */
.progress-all {
	width: 100%;
	height: 1px;
	background-color: #dee2e6;
}

/* 播放进度 文本 */
.time {
	display: inline-block;
	width: 90px;
	height: 21px;
	margin-left: 5px;
	text-align: center;
	color: rgba(128, 130, 133, 0.8);
	cursor: default;
	overflow: hidden;
}

/* 控制按钮 */
.control {
	width: 100%;
	height: 30px;
	margin-top: 19px;
}

.control a {
	margin: 0 5px;
	display: inline-block;
}

.control a:hover {
	opacity: 50%;
}

.control-btn {
	width: 130px;
	height: 30px;
	margin: 0 auto;
}

/* 上一首 */
.up {
	width: 30px;
	height: 30px;
	background: url(../img/up.png) no-repeat;
	background-size: 20px;
	background-position: 50% 50%;
}

/* 暂停播放 */
.play-pause {
	width: 30px;
	height: 30px;
	background: url(../img/play.png) no-repeat;
	background-size: 30px;
	background-position: 50% 50%;
}

/* 下一首 */
.down {
	width: 30px;
	height: 30px;
	background: url(../img/down.png) no-repeat;
	background-size: 20px;
	background-position: 50% 50%;
}

/* 右侧控制按钮 */
.control-right {
	/* width: 180px; */
	height: 30px;
	margin-left: calc(50vw + 150px);
	margin-top: -30px;
	display: flex;
	align-items: center;
}

/* 播放模式 */
.mode {
	width: 30px;
	height: 30px;
	background: url(../img/sequence.png) no-repeat;
	background-size: 20px;
	background-position: left 50%;
	cursor: pointer;
}

/* 声音控制 */
.volume {
	width: 30px;
	height: 30px;
	background: url(../img/volume.png) no-repeat;
	background-size: 20px;
	background-position: left 50%;
	cursor: pointer;
}

.volume-back {
	padding: 5px 0;
	cursor: pointer;
}

.volume-all {
	width: 100px;
	height: 2px;
	background-color: #e5e5e5;
}

.volume-now {
	width: 100px;
	height: 2px;
	margin-top: -2px;
	max-width: 100px;
	background-color: #5192fe;
}

.volume-text {
	margin-left: 10px;
	font-size: 14px;
}

JS

var myAduio = document.getElementsByTagName(‘audio‘)[0];
var divLyrics = document.getElementsByClassName(‘div-lyrics‘)[0];
var divTitle = document.getElementsByClassName(‘div-title‘)[0];
var lyricsTime = document.getElementsByClassName(‘lyrics-time‘)[0];
var lyricsTime_a = lyricsTime.getElementsByTagName(‘a‘);
var progressTime = document.getElementsByClassName(‘time‘)[0];
var nowLine = 0;
var lyricsMove = false;
var playState = false;
var lyrics, lyricsStyle, lyricsFirst, rollT;
var timeArray1 = new Array();
var timeArray2 = new Array();
var timeInterval = new Array();

window.onload = function () {
	initialLyrics();
	lyricsStyle = getComputedStyle(lyricsFirst, null);
	setLyrics(0);
	setMouseEvent();
	setTimeText();
};

// 设置事件
function setMouseEvent() {
	// 歌词拖拽
	let lyrics_Y, line;
	divLyrics.onmousedown = function (e) {
		if (lyricsMove == false) {
			lyricsTime_a[0].style.display = lyricsTime_a[1].style.display = lyricsTime.style.display =
				‘block‘;
			lyricsMove = true;
		}
		lyrics_Y = parseInt(lyricsStyle.marginTop);
		document.onmousemove = function (event) {
			lyricsFirst.style.marginTop =
				event.clientY - (e.clientY - lyrics_Y) + ‘px‘;
			line = Math.floor(-(parseInt(lyricsStyle.marginTop) - 170) / 34);
			if (line  lyrics.length - 1) {
				line = lyrics.length - 1;
			}
			lyricsTime_a[1].innerText = timeArray2[line];
		};
		document.onmouseup = function () {
			var lyrics_Y1 = parseInt(lyricsStyle.marginTop);
			setTimeout(function () {
				if (parseInt(lyricsStyle.marginTop) == lyrics_Y1) {
					lyricsMove = false;
					setLyrics(nowLine);
					lyricsTime_a[0].style.display = lyricsTime_a[1].style.display = lyricsTime.style.display =
						‘none‘;
				}
			}, 1000);
			document.onmousemove = null;
			document.onmouseup = null;
		};
		// 防止选中文字
		return false;
	};

	// 音量控制
	let volume_now = document.getElementsByClassName(‘volume-now‘)[0];
	let volume_back = document.getElementsByClassName(‘volume-back‘)[0];
	let volume_text = document.getElementsByClassName(‘volume-text‘)[0];
	let volume_a = document.getElementsByClassName(‘volume‘)[0];
	volume_back.onmousedown = function (e) {
		volume_now.style.width = e.offsetX + ‘px‘;
		myAduio.volume = e.offsetX / 100;
		volume_text.innerText = volume_now.clientWidth;
		volume_back.onmousemove = function (ev) {
			let volume = ev.offsetX;
			if (volume > 100) {
				volume = 100;
			}
			volume_now.style.width = volume + ‘px‘;
			myAduio.volume = volume / 100;
			volume_text.innerText = volume_now.clientWidth;
		};
		document.onmouseup = function () {
			if (myAduio.volume == 0) {
				volume_a.style.backgroundImage = ‘url(../img/mute.png)‘;
			} else {
				volume_a.style.backgroundImage = ‘url(../img/volume.png)‘;
			}
			volume_back.onmousemove = null;
			document.onmouseup = null;
		};
		return false;
	};

	// 进度控制
	let progress_now = document.getElementsByClassName(‘progress-now‘)[0];
	let progress_bar = document.getElementsByClassName(‘progress-bar‘)[0];
	progress_bar.onmousedown = function (e) {
		progress_now.style.width = e.offsetX + ‘px‘;
		myAduio.pause();
		myAduio.currentTime =
			(e.offsetX * myAduio.duration) / progress_bar.clientWidth;
		setTimeText();
		progress_bar.onmousemove = function (ev) {
			let progress = ev.offsetX;
			if (progress > progress_bar.clientWidth) {
				progress = progress_bar.clientWidth;
			}
			progress_now.style.width = progress + ‘px‘;
			myAduio.currentTime =
				(progress * myAduio.duration) / progress_bar.clientWidth;
			setTimeText();
		};
		document.onmouseup = function () {
			myAduio.play();
			for (var i = 0; i ‘ +
				lyricsArray[i].split(‘]‘)[1] +
				‘‘;
		} else {
			divLyrics.innerHTML +=
				‘

‘ + lyricsArray[i].split(‘]‘)[1] + ‘

‘; } } // 获取后续需要使用的变量 lyricsFirst = divLyrics.getElementsByTagName(‘p‘)[0]; lyrics = divLyrics.getElementsByTagName(‘p‘); // 计算每局歌词所在的秒数 timeArray1.push(0); for (var i = 0; i

其中JS中,获取页面属性跟歌词回弹是没有用到的,获取页面属性我写是&am

上一篇:Go-插入排序

下一篇:html基础


评论


亲,登录后才可以留言!