web123456

jQuery - QQ Music Case

The code can be found at/minmin233/QQmusic–jQuery

framework

head

在这里插入图片描述

<div class="header">
	<h1 class="logo"><a href="#"></a></h1>
	<ul class="login">
		<li>log in</li>
		<li>set up</li>
	</ul>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
.header{
	width: 100%;
	height: 45px;
	background: #31c27c;
}
.header .logo{
	float: left;
	margin-left: 20px;
}
.header .logo a{
	display: inline-block;
	width: 78px;
	height: 21px;
	background: url("../images/") no-repeat;
}
.header .login{
	float: right;
	line-height: 45px;
}
.header .login li{
	list-style: none;
	float: left;
	margin-right:20px;
	color:#fff;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

Middle Content Area

在这里插入图片描述
在这里插入图片描述

The center content area can be divided into one left and one right
The left side can be divided into one up and one down
1. Above are five buttons, buttons with borders, pictures, and text
2. Below is the song list, the songs in the song list can be selected, and the sub-menu will be displayed when the mouse is hovering.
2.1 Checkbox selected √ is a picture, set the position of this picture, get a class add remove
2.2 Disable li's check event
2.3 Beyond the appearance of scrollbars, optimize scrollbars, use plugins, there is the introduction of sequential problems
The right side can be divided into one up and one down
1. Above is the basic information of the song
2. Here are the lyrics on display
在这里插入图片描述

<div class="content_toolbar">
	<span><i></i>favorite</span>
	<span><i></i>add to</span>
	<span><i></i>downloading</span>
	<span><i></i>removing</span>
	<span><i></i>Empty the list</span>
</div>

<div class="content_list" data-mcs-theme="minimal-dark">
	<ul>
		<li class="list_title">
			<div class="list_check"><i></i></div>
			<div class="list_number"></div>
			<div class="list_name">lyrics</div>
			<div class="list_singer">vocalists</div>
			<div class="list_time">length of time</div>
		</li>
	</ul>
</div>

<li class="list_music">
	<div class="list_check"><i></i></div>
	<div class="list_number">1</div>
	<div class="list_name">Programming Development from Scratch
<div class="list_menu">
			<a href="javascript:;" title="Play"></a>
			<a href="javascript:;" title="Add"></a>
			<a href="javascript:;" title="Download"></a>
			<a href="javascript:;" title="Share."></a>
		</div>
	</div>
	<div class="list_singer">Li Nanjiang</div>
	<div class="list_time">
		<span>04:18</span>
		<a href="javascript:;" title="Delete"></a>
	</div>
</li>

<div class="song_info">
	<a href="javascript:;" class="song_info_pic">
		<img src="../images/" alt="">
	</a>
	<div class="song_info_name">Song Title:
<a href="javascript:;">Programming Development from Scratch</a>
	</div>
	<div class="song_info_singer">Singer's Name:
<a href="javascript:;">Li Nanjiang</a>
	</div>
	<div class="song_info_ablum">Album title:
<a href="javascript:;">Play from Scratch Series</a>
	</div>
</div>

<div class="song_lyric_container">
	<ul class="song_lyric">
		<li>1</li>
		<li>2</li>
	</ul>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
/*Elfigure*/
.content_toolbar span i{
	display: inline-block;
	width: 18px;
	height: 18px;
	background: url("../images/icon_sprite.png") no-repeat 0 0;
	margin-right: 10px;
	vertical-align: -5px;
}
.content_toolbar span:nth-child(1) i{
	background-position: -60px -20px;
}
.content_toolbar span:nth-child(2) i{
	background-position: -20px -20px;
}
.content_toolbar span:nth-child(3) i{
	background-position: -40px -240px;
}
.content_toolbar span:nth-child(4) i{
	background-position: -100px -20px;
}
.content_toolbar span:nth-child(5) i{
	background-position: -40px -300px;
}
/* scroll bar */
.content_left .content_list{
	width: 100%;
	height: 420px;
	overflow: auto;/* Beyond the appearance of scroll bars */
}
/*Each song*/
.content_list li{
	list-style: none;
	width: 100%;
	height: 50px;
	background: orange;
	opacity: 0.5;
	border-bottom: 1px solid rgba(255, 255, 255, 0.5);
	box-sizing: border-box;
	user-select: none; /*Disable checkmark**/
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

bottom control area

在这里插入图片描述

The progress bar consists of three parts, a cream colored background, a plain white foreground, and small dots;
The sound control area consists of an icon and a progress bar;
Icon Alignment;
Control icon switching, play button, loop mode button, like button, pure mode button
在这里插入图片描述

<!-- progress bar-->
<div class="music_progress_info">
	<div class="music_progress_top">
		<span class="music_progress_name">Programming Development from Scratch/ Li Jiangnan (1914-), PRC politician, prime minister 1987-1998, reportedly leader of the Gang of Four</span>
		<span class="music_progress_time">00:00 / 05:23</span>
	</div>
	<div class="music_progress_bar">
		<div class="music_progress_line">
			<div class="music_progress_dot"></div>
		</div>
	</div>
</div>
<!-- voice control zone-->
<div class="music_voice_info">
	<a href="javascript:;" class="music_voice_icon"></a>
	<div class="music_voice_bar">
		<div class="music_voice_line">
			<div class="music_voice_dot"></div>
		</div>
	</div>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
/*Stick to the bottom*/
.footer{
	width: 100%;
	height: 80px;
	position: absolute;
	left: 0;
	bottom: 0;
}
/* Progress bar */
.footer_in .music_progress_info{
	display: inline-block;
	width: 670px;
	height: 40px;
	position: relative;
	top:10px;
}
.music_progress_info .music_progress_top{
	width: 100%;
	height: 30px;
	color: #fff;
	line-height: 30px;
}
.music_progress_top .music_progress_name{
	float: left;
	opacity: 0.5;
}
.music_progress_top .music_progress_name:hover{
	opacity: 1;
}
.music_progress_top .music_progress_time{
	float: right;
	opacity: 0.5;
}
.music_progress_info .music_progress_bar{
	width: 100%;
	height: 4px;
	background: rgba(255, 255,255,0.5);
	margin-top: 5px;
}
.music_progress_bar .music_progress_line{
	height: 100%;
	background: #fff;
}
.music_progress_line .music_progress_dot{
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: #fff;
	position: relative;
	top:-5px;
}
/* Sound control area */
.footer_in .music_voice_info{
	display: inline-block;
	width: 100px;
	height: 40px;
	position: relative;
	top: 10px;
}
.music_voice_info .music_voice_icon{
	width: 26px;
	height: 21px;
	background-position: 0 -144px;
	position: absolute;
	left: 0;
	top: 10px;
}
.music_voice_info .music_voice_bar{
	width: 70px;
	height: 4px;
	background: rgba(255, 255,255,0.5);
	position: absolute;
	right: 0;
	top: 18px;
}
.music_voice_bar .music_voice_line{
	height: 100%;
	background: #fff;
}
.music_voice_line .music_voice_dot{
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: #fff;
	position: relative;
	top:-5px;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

Middle content area and bottom control area with layout

Centering the shape

.content .content_in{
	width: 1200px;
	height: 100%;
	margin:0 auto;
}
.footer .footer_in{
	width: 1200px;
	height: 100%;
	margin:0 auto;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

type

Checkbox click highlighting

.content_list .list_check i{
	display: inline-block;
	width: 14px;
	height: 14px;
	border: 1px solid #fff;
	opacity: 0.5;
}
.content_list .list_checked i{
	background: url("../images/icon_sprite.png") no-repeat -60px -80px;
	opacity: 1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Highlight on mouseover submenu

.list_menu a{
	display: inline-block;
	width: 36px;
	height: 36px;
	background: url("../images/icon_list_menu.png") no-repeat 0 0;
	opacity: 0.5;
}
.list_menu a:hover{
	opacity: 1;
}

.content_list .list_time a{
	width: 36px;
	height: 36px;
	float: left;
	background: url("../images/icon_list_menu.png") no-repeat -120px -160px;
	margin-top: 5px;
	display: none;
	opacity: 0.5;
}
.content_list .list_time a:hover{
	opacity: 1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Gaussian Blur Background

<div class="mask_bg"></div>
<div class="mask"></div>
  • 1
  • 2
.mask_bg{
	position: absolute;
	left: 0;
	top: 0;
	z-index: -2;
	width: 100%;
	height: 100%;
	background: url("../images/") no-repeat 0 0;
	background-size: cover;/* Fill the whole screen */
	filter: blur(100px);/* the larger the value the more blurred */
}
.mask{
	position: absolute;
	left: 0;
	top: 0;
	z-index: -1;
	width: 100%;
	height: 100%;
	background:rgba(0,0,0,0.35);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

event

Load Song List

There are cross-domain issues;
The only way to add events to dynamically created elements is through event delegates;

// 1. Load song list
getPlayerList();
function getPlayerList() {
	// You can load local files as well as network files.
	$.ajax({
		url: "./source/",
		dataType: "json",
		success: function (data) {
			player.musicLists = data;
			// Iterate over the fetched data to create each piece of music
			$.each(data, function (index, ele) {
				var $item = createMusicItem(index, ele);
				var $musicList = $(".content_list ul");
				$musicList.append($item);
			});
			initMusicInfo(data[0]);
			initLyricInfo(data[0]);
		},
		error: function (e) {
			console.log(e);
		}
	});
}

// Define a method to create a piece of music
function createMusicItem(index, music){
	var $item = $(`<li class="list_music">
								<div class="list_check"><i></i></div>
								<div class="list_number">`+ (index+1) + `</div>
								<div class="list_name">`+ music.name +`
<div class="list_menu">
<a href="javascript:;" title="play" class="list_menu_play"></a>
<a href="javascript:;" title="Add"></a>
<a href="javascript:;" title="Download"></a>
<a href="javascript:;" title="Share"></a>
</div>
</div>.
<div class="list_singer">`+ music.singer +`</div>
								<div class="list_time">
									<span>` + music.time + `</span>
<a href="javascript:;" title="Delete" class="list_menu_del"></a>
</div>
</li>`);
	$item.get(0).index = index; // get the index of the song in the native li
	$item.get(0).music = music; // Get the song in the native li
	return $item;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

Playback icon switching

Find the dynamically added to the play button and add a submenu play button listener; the
Play and pause buttons toggle with each other.
When the first song is clicked to play and then the second song is clicked to play, the first song is restored;
Synchronize the bottom play button, when you click the play button of the music above, the bottom play button will be updated synchronously

.list_menu .list_menu_play1{
	background-position: -80px -200px !important;
}
  • 1
  • 2
  • 3
// Add a listener for the submenu play button.
var $musicPlay = $(".music_play");
$(".content_list").delegate(".list_menu_play","click",function(){
	// 1. Toggle the playback icon
	$(this).toggleClass("list_menu_play1");
	// 2. Restore other playback icons
	$(this).parents(".list_music").siblings().find(".list_menu_play").removeClass("list_menu_play1");
	// 3. Synchronize the bottom play button
	if ($(this).attr("class").indexOf("list_menu_play1") != -1){
		// The current submenu is playing
		$musicPlay.addClass("music_play1");
	}else{
		// The current submenu is not playing
		$musicPlay.removeClass("music_play1");
	}
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Text highlighting by clicking the play button

// Make text highlighted
$(this).parents(".list_music").find("div").css("color","#fff");
// Restore other text
$(this).parents(".list_music").siblings().find("div").css("color", "rgba(255,255,255,0.5)");
  • 1
  • 2
  • 3
  • 4

Serial number animation

Hide the serial number and show the playback animation while the music is playing, the
The playback animation is a background image, add a new class to toggle whether or not to show the playback animation

.content_list .list_number{
	width: 20px;
	height: 100%;
}
.content_list .list_number1{
	color: transparent !important;
	background: url("../images/") no-repeat 0 center;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
// Toggle the status of the serial number
$(this).parents(".list_music").find(".list_number").toggleClass("list_number1");
// Restore the status of other serial numbers
$(this).parents(".list_music").siblings().find(".list_number").removeClass("list_number1");
  • 1
  • 2
  • 3
  • 4

Music playback pause

playMusic:function(index,music){
	// Determine if it's the same music
	if(this.currentIndex == index){
		// The same music
		if(this.audio.paused){
			this.audio.play();
		}else{
			this.audio.pause();
		} 
	}else{
		// Not the same song
		this.$audio.attr("src",music.link_url);
		this.audio.play();
		this.currentIndex = index;
	}
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Bottom music control

Play button.
If no music has ever been played, clicking the play button will play the 0th music by default, the
Playing the 0th track is equivalent to clicking on the sub-menu of the 0th track, the
First find the li of the 0th music, then find the play button in the li and trigger a click event;
If the music has already played, click to either pause or resume playing;
Previous song.
Current index -1, when reduced to a negative number, return to last song
Next song.
Current index +1, when greater than the length of the song, return to the first song

// 4. Listen for clicks on the play button in the bottom control area.
$musicPlay.click(function(){
	// Determine if music has been played
	if(player.currentIndex == -1){
		// No music played
		$(".list_music").eq(0).find(".list_menu_play").trigger("click");
	} else {
			$(".list_music").eq(player.currentIndex).find(".list_menu_play").trigger("click");
	}
})
// 5. Listen for the click of the previous button in the bottom control area.
$(".music_pre").click(function () {			
	$(".list_music").eq(player.preIndex()).find(".list_menu_play").trigger("click");
})
// 6. Listen for the click of the next button in the bottom control area.
$(".music_next").click(function () {
	$(".list_music").eq(player.nextIndex()).find(".list_menu_play").trigger("click");
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Delete Music Button

To find the track that corresponds to the delete button, and to have the data synchronized.
The serial numbers of the songs are reordered after deletion;
Deleted is the currently playing music, then the next song is played automatically, which is equivalent to clicking the next button;
If the deleted song is in front of the one that is playing, then clicking on the next song will play the next song, because after deleting the song, the song is reordered, but the currentIndex doesn't change.

// 7. Listen for the Delete button to be clicked.
		$(".content_list").delegate(".list_menu_del","click",function(){
	// Find the music that was clicked
	var $item = $(this).parents(".list_music");
	// Determine if the deleted music is currently playing.
	if($item.get(0).index == player.currentIndex){
		$(".music_next").trigger("click");
	}
	$item.remove();
	player.changeMusicLists($item.get(0).index);
	// Reordering
	$(".list_music").each(function(index,ele){
		ele.index = index;
		$(ele).find(".list_number").text(index + 1);
	})
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Switching of song information

Initialized with the information of the 0th song
Switching song information during playback
1. Switching of song information on the right side of the center content area
2. Bottom control area in the middle of the progress bar song information switching
3. The whole background of the color tone song information switching

// 2. Initialize song information
function initMusicInfo(music) {
	$(".song_info_pic img").attr("src", music.cover);
	$(".song_info_name a").text(music.name);
	$(".song_info_singer a").text(music.singer);
	$(".song_info_ablum a").text(music.ablum);

	$(".music_progress_name").text(music.name + " / " + music.singer);
	$(".music_progress_time").text("00:00 / " + music.time);

	$(".mask_bg").css("background", "url('" + music.cover + "')");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
'
(of a computer) run

progress bar

Wrap the progress bar in a separate class

(function (window) {
	function Progress($progressBar, $progressLine, $progressDot) {
		return new Progress.prototype.init($progressBar, $progressLine, $progressDot);
	}
	Progress.prototype = {
		constructor: Progress,
		init: function ($progressBar, $progressLine, $progressDot) {
			this.$progressBar = $progressBar; 
			this.$progressLine = $progressLine;
			this.$progressDot = $progressDot;
		},
		isMove:false,
		progressClick:function(callBack){
			var $this = this; //whoever calls this method, this is, at this point this is progress
			// Listen for background clicks
			this.$progressBar.click(function(event){
				// Get the default position of the background from the window
				var normalLeft = $(this).offset().left; // This is the progressBar.
				// Get the position of the click from the window
				var eventLeft = event.pageX;
				// Set the width of the foreground
				$this.$progressLine.css("width", eventLeft - normalLeft);
				// Set the position of the dot
				$this.$progressDot.css("left", eventLeft - normalLeft);
				
				// Calculate the scale of the progress bar
				var value = (eventLeft - normalLeft) / $(this).width();
				callBack(value);
			})
		},
		progressMove:function(callBack){
			var $this = this;
			// Get the default position of the background from the window
			var normalLeft = this.$progressBar.offset().left;
			var eventLeft; //Click position from the window
			// Get the width of the progress bar
			var barWidth = this.$progressBar.width();
			// 1. Listen for mouse presses.
			this.$progressBar.mousedown(function(){
				// 2. Listening for mouse movements
				$(document).mousemove(function(event){
					$this.isMove = true;
					// Get the position of the click from the window
					eventLeft = event.pageX;
					var offset = eventLeft - normalLeft;
					if (offset >= 0 && offset <= barWidth){
						// Set the width of the foreground
						$this.$progressLine.css("width", offset);
						$this.$progressDot.css("left", offset);
					}
					/* // Calculate the scale of the progress bar
var value = (eventLeft - normalLeft) / $(this).width();;;
callBack(value); */
				})

			})
			// 3. Listen for mouse popups.
			$(document).mouseup(function () {
				$(document).off("mousemove");
				this.isMove=false;
				// Calculate the scale of the progress bar
				var value = (eventLeft - normalLeft) / $this.$progressBar.width();;
				callBack(value);
			})
		},
		setProgress:function(value){
			if(this.isMove) return;
			if(value < 0 || value > 100) return;
			this.$progressLine.css({
				width:value+"%"
			});
			this.$progressDot.css({
				left: value + "%"
			});
		}
	}
	Progress.prototype.init.prototype = Progress.prototype;
	window.Progress = Progress;
})(window);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

strike (on the keyboard)

Manipulate Background, Manipulate Foreground, Manipulate Dots
Set the foreground, set the position of the dots

drag

Press and hold the mouse, then drag and drop
Keep modifying the width of the foreground and the position of the dots as you drag and drop;
Stopping the modification after the mouse pops up is the event that removes the drag and drop
There are three events, mouse press, move, and pop;
Among them, the mouse's movement event must be executed in the mouse's press event, listening to the movement event can not be used to listen to the progress bar, if so, the mouse can only be in the progress bar to have the effect of the

synchronization

Synchronization of playback time

Listens to the progress of the currently played song.timeupdate
Get the total duration of the music currently playing, and the duration that has already been played

Synchronization of progress bars

Calculating the playback ratio

Song Synchronization

Click on the dots and drag and drop the dots
You can get the width of the foreground at this point, the width of the background
You can get the total duration of getting the music
Setting the music skip position

The width of the foreground is set when dragging and dropping
The width of the foreground is set when synchronizing the progress bar
There's a conflict.

Drag and drop doesn't set when the music starts playing, the
Set only when you let go

make superior

Put all the code related to playback control into the

// 9. Listen to the progress of the playback
player.$audio.on("timeupdate",function(){
	var duration = player.getMusicDuration();
	var currentTime = player.getMusicCurrentTime();
	var timeStr = formatDate(currentTime, duration);
	$(".music_progress_time").text(timeStr);
})

// Formatting time
function formatDate(currentTime, duration){
	var endMin = parseInt(duration / 60); // Minutes
	var endSec = parseInt(duration % 60); // Seconds
	if(endMin < 10){
		endMin = "0" + endMin;
	}
	if (endSec < 10) {
		endSec = "0" + endSec;
	}
	var startMin = parseInt(currentTime / 60);
	var startSec = parseInt(currentTime % 60);
	if (startMin < 10) {
		startMin = "0" + startMin;
	}
	if (startSec < 10) {
		startSec = "0" + startSec;
	}
	return startMin + ":" + startSec + " / " + endMin + ":" + endSec ;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
musicTimeUpdate:function(callBack){
	var $this = this;
	this.$audio.on("timeupdate", function () {
		var duration = $this.audio.duration;
		var currentTime = $this.audio.currentTime;
		var timeStr = $this.formatDate(currentTime, duration);
		callBack(currentTime, duration, timeStr);
	});
},
// Formatting time
formatDate:function (currentTime, duration){
	var endMin = parseInt(duration / 60); // Minutes
	var endSec = parseInt(duration % 60); // Seconds
	if (endMin < 10) {
		endMin = "0" + endMin;
	}
	if (endSec < 10) {
		endSec = "0" + endSec;
	}
	var startMin = parseInt(currentTime / 60);
	var startSec = parseInt(currentTime % 60);
	if (startMin < 10) {
		startMin = "0" + startMin;
	}
	if (startSec < 10) {
		startSec = "0" + startSec;
	}
	return (startMin + ":" + startSec + " / " + endMin + ":" + endSec);
}

// 9. Listen to the progress of the playback
player.musicTimeUpdate(function (currentTime, duration, timeStr){
	$(".music_progress_time").text(timeStr);
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

voice control

Sound icon control

// Sound switch toggle
musicVoiceSeekTo: function (value){
	// Values in the range 0-1
	this.audio.volume = value;
}

// 10. Listening for sound button clicks
$(".music_voice_icon").click(function(){
	// Switching icons
	$(this).toggleClass("music_voice_icon1");
	// Sound switching
	if ($(this).attr("class").indexOf("music_voice_icon1") != -1){
		// Sound off
		player.musicVoiceSeekTo(0);
	} else{
		player.musicVoiceSeekTo(1);
	}
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Control of the sound progress bar

var $voiceBar = $(".music_voice_bar");
var $voiceLine = $(".music_voice_line");
var $voiceDot = $(".music_voice_dot");
var voiceProgress = new Progress($voiceBar, $voiceLine, $voiceDot);
voiceProgress.progressClick(function (value) {
	player.musicVoiceSeekTo(value);
});
voiceProgress.progressMove(function (value) {
	player.musicVoiceSeekTo(value);
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

bug

The progress bar can be dragged out and judged

Lyrics control

Lyrics Loading

loadLyric:function(callBack){
	var $this = this;
	$.ajax({
		url: $this.path,
		dataType: "text",
		success: function (data) {
			$this.parseLyric(data);
			callBack();
		},
		error: function (e) {
			console.log(e);
		}
	})
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

lyrics analysis

parseLyric:function(data){
	var $this = this;
	var array = data.split("\n");
	var timeReg = /\[(\d*:\d*\.\d*)\]/;
	// Iterate through and take out each lyric
	$.each(array,function(index,ele){
		// Processing Lyrics
	    var lrc = ele.split("]")[1];
		// Exclude the ones without lyrics
		if(lrc.length <= 1) return true;
		$this.lyrics.push(lrc);

		// Match the time with a regular expression [00:00.92].
		var res = timeReg.exec(ele);
		if(res == null) return true;
		var timeStr = res[1]; // 00:00.92
		var res1 = timeStr.split(":");
		var min = parseInt(res1[0]) * 60; // Minutes - seconds
		var sec = parseFloat(res1[1]); // seconds
		var time = parseFloat(Number(min + sec).toFixed(2));// Retain two decimal places
		$this.times.push(time);
	})
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Create a list of lyrics based on the lyrics

// 3. Initialize lyrics information
function initLyricInfo(music){
	var lyric = new Lyric(music.link_lrc);
	var $lyricContainer = $(".song_lyric");
	lyric.loadLyric(function(){
		// Create a list of lyrics
		$.each(lyric.lyrics,function(index,ele){
			var $item = $("<li>"+ ele +"</li>");
			$lyricContainer.append($item);
		})
	});
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
'
(of a computer) run

Lyrics synchronization and scrolling

Listen to the progress of the currently playing music.
Get the current playing time to pass to the lyrics object.
Using a match between the current playback time and the saved time, the
Returns the matched index.
Highlight the corresponding lyrics to scroll to the corresponding position of the
Toggles the information of the lyrics while clicking on the sub-menu play button.
When switching lyrics information, the previously saved information is cleared.

currentIndex:function(currentTime){
	if(currentTime >= this.times[0]){
		this.index ++;
		this.times.shift(); // Remove the top element of the array
	}
	return this.index;
}

// 8. Listen to the progress of the playback
player.musicTimeUpdate(function (currentTime, duration, timeStr){
	// Synchronize lyrics
	var index = lyric.currentIndex(currentTime);
	var $item = $(".song_lyric li").eq(index);
	$item.addClass("cur");
	$item.siblings().removeClass("cur");
	//Lyrics scrolling
	if(index <= 2) return;
	$(".song_lyric").css({
		marginTop:((-index + 2) * 30)
	})
})

// 3. Listen for submenu play button clicks.
$(".content_list").delegate(".list_menu_play", "click", function () {
	// 3.7 Toggling Lyrics Information
	initLyricInfo($music.get(0).music);
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27