?使用 HTML、CSS 和 JS 創(chuàng)建在線音樂播放器(含免費完整源碼)?


今天我將帶著大家使用 HTML、CSS 和 JS創(chuàng)建?音樂播放器,沒有使用任何其他庫。我們的音樂播放器具有三個部分。主屏幕、播放器部分和播放列表部分。我們的主頁部分有一個平滑的工作滑塊,也有水平滾動。這個音樂播放器最好的部分是它最小化了音樂播放器。是的,您可以最小化和最大化播放器本身。使這個項目成為一個很棒的音樂播放器。
??使用 HTML、CSS 和 JS 創(chuàng)建在線音樂播放器??
?? 在線演示地址
?? 完整代碼結(jié)構(gòu)
?? home-section 首頁部分
?? player-section 播放器部分
?? playlist-section 播放列表部分
? navigation 導(dǎo)航部分
?? music 音樂部分
?? wuhu ! 起飛 !
?? 完整源碼下載
?? 在線演示地址
https://haiyong.site/tools/yinyue/
?? 完整代碼結(jié)構(gòu)
在我們開始編寫代碼之前。雖然它不是 Nodejs 應(yīng)用程序,但我們至少應(yīng)該看到它的文件夾結(jié)構(gòu)。

你可以看到我們有一個data.js文件,該文件包含我們的音樂相關(guān)數(shù)據(jù)。你可以在下面看到。
let songs = [ ? ?{ ? ? ? ?name: 'song 1', ? ? ? ?path: 'assets/musics/Song 1.mp3', ? ? ? ?artist: 'artist 1', ? ? ? ?cover: 'assets/images/cover 1.png' ? ?}, ? ?{ ? ? ? ?name: 'song 2', ? ? ? ?path: 'assets/musics/Song 2.mp3', ? ? ? ?artist: 'artist 2', ? ? ? ?cover: 'assets/images/cover 2.png' ? ?}, ? ?// 剩下8首歌曲格式同上]
我們在這里存儲了音樂相關(guān)數(shù)據(jù)。
然后現(xiàn)在讓我們對主頁部分進(jìn)行編碼。
?? home-section 首頁部分
打開index.html和內(nèi)部從編寫基本的 HTML 結(jié)構(gòu)開始。還鏈接style.css和兩個 JS 文件。記得data.js在app.js. 否則我們將無法訪問數(shù)據(jù)。
完成鏈接所有文件后,讓我們創(chuàng)建第一件事。圖像輪播。內(nèi)部身體標(biāo)簽代碼這個。
<section class="home-section"> ? ?<div class="carousel"> ? ? ? ?<img src="assets/images/cover 1.png" class="active" alt=""> ? ? ? ?<img src="assets/images/cover 2.png" alt=""> ? ? ? ?<img src="assets/images/cover 3.png" alt=""> ? ? ? ?<img src="assets/images/cover 4.png" alt=""> ? ? ? ?<img src="assets/images/cover 5.png" alt=""> ? ?</div></section>
注意 - 將旋轉(zhuǎn)木馬包裹在home-section
元素內(nèi)。
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap'); *{ ? ?margin: 0; ? ?padding: 0; ? ?box-sizing: border-box;}:root{ ? ?--background: #141414; ? ?--text-color: #fff; ? ?--primary-color: #63ff69; ? ?--secondary-color: #000; ? ?--alpha-color: rgba(0, 0, 0, 0.5); ? ?--shadow: 0 15px 40px var(--alpha-color);}html{ ? ?background: var(--background); ? ?display: flex; ? ?justify-content: center;}body{ ? ?width: 100%; ? ?height: 100vh; ? ?max-width: 375px; ? ?position: relative; ? ?background: var(--background); ? ?font-family: 'roboto', sans-serif; ? color: var(--text-color);}::-webkit-scrollbar{ ? display: none;}.home-section{ ? width: 100%; ? padding: 20px; ? height: 100%; ? padding-bottom: 100px; ? overflow-y: auto;}/* carousel */.carousel{ ? width: 100%; ? height: 200px; ? overflow: hidden; ? border-radius: 20px; ? box-shadow: var(--shadow); ? position: relative;}.carousel img{ ? position: absolute; ? width: 100%; ? height: 100%; ? object-fit: cover; ? opacity: 0; ? transition: 1s;}.carousel img.active{ ? opacity: 1;}
您可以看到我們在這里使用了 CSS 變量,因此我們將來可以輕松更改此音樂播放器主題。
輸出

請注意,這是為移動視圖設(shè)計的,這就是為什么我使用 chrome 檢查器以移動尺寸查看它的原因。
現(xiàn)在創(chuàng)建水平滾動播放列表。放在home-section
里面
HTML
<h1 class="heading">最近播放</h1><div class="playlists-group"> <div class="playlist-card"> <img src="assets/images/cover 9.png" class="playlist-card-img" alt=""> <p class="playlist-card-name">華語熱歌</p> </div> <div class="playlist-card"> <img src="assets/images/cover 2.png" class="playlist-card-img" alt=""> <p class="playlist-card-name">古風(fēng)戲腔</p> </div> //+3 </div><h1 class="heading">根據(jù)你的喜好</h1><div class="playlists-group"> <div class="playlist-card"> <img src="assets/images/cover 12.png" class="playlist-card-img" alt=""> <p class="playlist-card-name">失戀回憶</p> </div> <div class="playlist-card"> <img src="assets/images/cover 12.png" class="playlist-card-img" alt=""> <p class="playlist-card-name">經(jīng)典老歌</p> </div> //+3 </div>
CSS
.heading{ ? margin: 30px 0 10px; ? text-transform: capitalize; ? font-weight: 400; ? font-size: 30px;}/* playlists card */.playlists-group{ ? position: relative; ? width: 100%; ? min-height: 200px; ? height: auto; ? display: flex; ? flex-wrap: nowrap; ? overflow-x: auto;}.playlist-card{ ? flex: 0 0 auto; ? max-width: 150px; ? height: 100%; ? margin-right: 20px;}.playlist-card-img{ ? width: 100%; ? height: 150px; ? object-fit: cover; ? border-radius: 20px;}.playlist-card-name{ ? width: 100%; ? text-align: justify; ? font-size: 20px; ? text-transform: capitalize; ? padding: 5px;}
輸出

我們完成了home section
。但是我們的旋轉(zhuǎn)木馬還不起作用,所以讓我們使用 js 讓它工作。打開app.js文件并開始編碼。
const carousel = [...document.querySelectorAll('.carousel img')];let carouselImageIndex = 0;const changeCarousel = () => { ? ?carousel[carouselImageIndex].classList.toggle('active'); ? ?if(carouselImageIndex >= carousel.length - 1){ ? ? ? ?carouselImageIndex = 0; ? ?} else{ ? ? ? ?carouselImageIndex++; ? ?} ? ?carousel[carouselImageIndex].classList.toggle('active');}setInterval(() => { ? changeCarousel();}, 3000);
您可以看到我們的輪播元素,每 3 秒切換一次圖像active類。

現(xiàn)在讓我們制作我們的播放器部分。
?? player-section 播放器部分
首先使其最小化視圖。
<section class="music-player-section"> ? ?<img src="assets/images/back.png" class="back-btn icon hide" alt=""> ? ?<img src="assets/images/nav.png" class="nav-btn icon hide" alt=""> ? ?<h1 class="current-song-name">song 1</h1> ? ?<p class="artist-name hide">artist 1</p> ? ?<img src="assets/images/cover 1.png" class="cover hide" alt=""> ? ?<div class="seek-bar-container"> ? ? ? ?<input type="range" class="music-seek-bar" value="0"> ? ? ? ?<p class="current-time hide">00 : 00</p> ? ? ? ?<p class="duration hide">00 : 00</p> ? ?</div> ? ?<div class="controls"> ? ? ? ?<span class="fas fa-redo"></span> ? ? ? ?<div class="main"> ? ? ? ? ? ?<i class="fas fa-backward active"></i> ? ? ? ? ? ?<i class="fas fa-play active"></i> ? ? ? ? ? ?<i class="fas fa-pause"></i> ? ? ? ? ? ?<i class="fas fa-forward active"></i> ? ? ? ?</div> ? ? ? ?<input type="range" class="volume-slider" max="1" value="1" step="0.1"> ? ? ? ?<span class="fas fa-volume-up"></span> ? ?</div></section>
如果你看到我們的播放器結(jié)構(gòu),你會注意到我們有很多hide元素的類。此類hide指示元素將在最小化視圖中隱藏。我們?yōu)樗性靥峁┝讼嗤念?,因此我們可以輕松地在 CSS 中設(shè)置它們的樣式。
.music-player-section{ ? width: 100%; ? height: 100px; ? position: fixed; ? bottom: 0; ? left: 0; ? background: var(--alpha-color); ? backdrop-filter: blur(50px); ? transition: 1s;}.music-seek-bar{ ? -webkit-appearance: none; ? width: 100%; ? position: absolute; ? top: -4px; ? height: 8px; ? background: var(--secondary-color); ? overflow: hidden;}.music-seek-bar::-webkit-slider-thumb{ ? -webkit-appearance: none; ? height: 10px; ? width: 5px; ? background: var(--primary-color); ? cursor: pointer; ? box-shadow: -400px 0 0 400px var(--primary-color);}.current-song-name{ ? font-weight: 300; ? font-size: 20px; ? text-align: center; ? margin-top: 5px; ? text-transform: capitalize;}.controls{ ? position: relative; ? width: 80%; ? margin: auto; ? display: flex; ? justify-content: center; ? align-items: center; ? height: 60px; ? font-size: 30px;}.controls span{ ? display: none; ? opacity: 0; ? transition: 1s;}.music-player-section.active .controls{ ? justify-content: space-between;}.music-player-section.active .controls span{ ? font-size: 25px; ? display: block; ? opacity: 0.5;}.music-player-section.active .controls span.active{ ? color: var(--primary-color); ? opacity: 1;}.controls .main i{ ? margin: 0 5px; ? display: none;}.controls .main i.active{ ? display: inline;}
現(xiàn)在讓我們創(chuàng)建最大化視圖的樣式。
.music-player-section .hide{ ? display: none; ? opacity: 0; ? transition: 1s;}.music-player-section.active .hide{ ? display: block; ? opacity: 1;}.music-player-section.active{ ? width: 100%; ? height: 100%; ? padding: 30px; ? display: flex; ? flex-direction: column;}.music-player-section.active .music-seek-bar{ ? position: relative; ? display: block; ? border-radius: 50px; ? margin: auto;}.music-player-section.active .current-song-name{ ? font-size: 40px;}.music-player-section.active .controls{ ? width: 100%; ? font-size: 50px;}.artist-name{ ? text-align: center; ? font-size: 20px; ? text-transform: capitalize;}.cover{ ? width: 30vh; ? height: 30vh; ? object-fit: cover; ? margin: auto; ? border-radius: 20px; ? box-shadow: var(--shadow);}.current-time{ ? position: absolute; ? margin-top: 5px; ? left: 30px;}.duration{ ? position: absolute; ? margin-top: 5px; ? right: 30px;}.icon{ ? position: absolute; ? top: 60px; ? transform: scale(1.3);}.back-btn{ ? left: 40px;}.nav-btn{ ? right: 40px;}/* volume button */.volume-slider{ ? -webkit-appearance: none; ? width: 100px; ? height: 40px; ? position: absolute; ? right: -35px; ? bottom: 80px; ? transform: rotate(-90deg); ? border-radius: 20px; ? background: var(--alpha-color); ? overflow: hidden; ? opacity: 0; ? display: none;}.volume-slider.active{ ? opacity: 1; ? display: block;}.volume-slider::-webkit-slider-thumb{ ? -webkit-appearance: none; ? height: 40px; ? width: 10px; ? background: var(--primary-color); ? box-shadow: -200px 0 1px 200px var(--primary-color);}
輸出

并檢查這些樣式,現(xiàn)在像這樣將active
添加到 class?music-player-section
?中去。
<section class="music-player-section active">...</section>
輸出

我們最終會讓這個播放器發(fā)揮作用?,F(xiàn)在從player section類刪除這個active。讓我們創(chuàng)建播放列表部分。
?? playlist-section 播放列表部分
<section class="playlist active"> ? ?<img src="assets/images/back.png" class="back-btn icon" alt=""> ? ?<h1 class="title">播放列表</h1> ? ?<div class="queue active"> ? ? ? ?<div class="queue-cover"> ? ? ? ? ? ?<img src="assets/images/cover 1.png" alt=""> ? ? ? ? ? ?<i class="fas fa-pause"></i> ? ? ? ?</div> ? ? ? ?<p class="name">song 1</p> ? ?</div> ? ?// +7</section>
CSS
.playlist{ ? width: 100%; ? height: 100%; ? position: fixed; ? top: 0; ? right: -100%; ? padding: 30px 0; ? background: var(--background); ? z-index: 3; ? transition: 1s; ? overflow: auto;}.playlist.active{ ? right: 0;}.title{ ? font-weight: 300; ? font-size: 40px; ? text-align: center; ? margin-top: 15px; ? text-transform: capitalize; ? margin-bottom: 30px;}.queue{ ? width: 100%; ? height: 80px; ? padding: 0 30px; ? display: flex; ? align-items: center; ? border-top: 2px solid var(--alpha-color);}.queue-cover{ ? width: 60px; ? height: 60px; ? border-radius: 10px; ? overflow: hidden; ? margin-right: 20px; ? position: relative;}.queue-cover img{ ? width: 100%; ? height: 100%; ? object-fit: cover;}.queue-cover i{ ? position: absolute; ? top: 50%; ? left: 50%; ? transform: translate(-50%, -50%); ? font-size: 30px; ? color: var(--primary-color); ? display: none;}.queue.active i{ ? display: block;}.queue .name{ ? font-size: 22px; ? text-transform: capitalize;}
輸出

我們已經(jīng)完成了所有的造型。active也從播放列表部分刪除類。
現(xiàn)在讓我們 JS 使這個音樂應(yīng)用程序功能齊全。
? navigation 導(dǎo)航部分
我們的音樂播放器中有三個部分。因此,為這個應(yīng)用程序設(shè)置導(dǎo)航系統(tǒng)對我們來說非常重要。通過它我們可以輕松地從一個部分導(dǎo)航到另一個部分。對?所以編碼這個。
/////////////////////導(dǎo)航////////////////////////切換音樂播放器const musicPlayerSection = document.querySelector('.music-player-section');let clickCount = 1;musicPlayerSection.addEventListener('click', () => { ? ?if(clickCount >= 2){ ? ? ? ?musicPlayerSection.classList.add('active'); ? ? ? ?clickCount = 1; ? ? ? ?return; ? ?} ? ?clickCount++; ? ?setTimeout(() => { ? ? ? ?clickCount = 1; ? ?}, 250);})/////// 從音樂播放器返回const backToHomeBtn = document.querySelector('.music-player-section .back-btn');backToHomeBtn.addEventListener('click', () => { ? ?musicPlayerSection.classList.remove('active');})/////// 訪問播放列表const playlistSection = document.querySelector('.playlist');const navBtn = document.querySelector('.music-player-section .nav-btn');navBtn.addEventListener('click', () => { ? ?playlistSection.classList.add('active');})////////// 從播放列表返回到音樂播放器const backToMusicPlayer = document.querySelector('.playlist .back-btn');backToMusicPlayer.addEventListener('click', () => { ? ?playlistSection.classList.remove('active');})//////導(dǎo)航完成////////////////
這是基本的 JS,我還在代碼中添加了注釋。因此,如果您對此代碼有任何疑問,請隨時在討論中問我。我們的導(dǎo)航完成了。所以讓我們創(chuàng)建我們的音樂播放器。
?? music 音樂部分
對于音樂播放器,我們的頁面中需要一個音頻源,但現(xiàn)在我們沒有。為此在?index.html
?中創(chuàng)建一個音頻元素。在 body 標(biāo)記的開頭創(chuàng)建此元素。
<audio src="" id="audio-source"></audio>
現(xiàn)在我們必須創(chuàng)建很多函數(shù),所以在開始之前讓我們快速選擇我們可能需要進(jìn)行操作的所有元素。
/////// 音樂let currentMusic = 0;const music = document.querySelector('#audio-source');const seekBar = document.querySelector('.music-seek-bar');const songName = document.querySelector('.current-song-name');const artistName = document.querySelector('.artist-name');const coverImage = document.querySelector('.cover');const currentMusicTime = document.querySelector('.current-time');const musicDuration = document.querySelector('.duration');const queue = [...document.querySelectorAll('.queue')];// 在此處選擇所有按鈕const forwardBtn = document.querySelector('i.fa-forward');const backwardBtn = document.querySelector('i.fa-backward');const playBtn = document.querySelector('i.fa-play');const pauseBtn = document.querySelector('i.fa-pause');const repeatBtn = document.querySelector('span.fa-redo');const volumeBtn = document.querySelector('span.fa-volume-up');const volumeSlider = document.querySelector('.volume-slider');
現(xiàn)在設(shè)置音樂源。
// 音樂設(shè)置功能const setMusic = (i) => { ? ?seekBar.value = 0; ? ?let song = songs[i]; ? ?currentMusic = i; ? ?music.src = song.path; ? ?songName.innerHTML = song.name; ? ?artistName.innerHTML = song.artist; ? ?coverImage.src = song.cover; ? ?setTimeout(() => { ? ? ? ?seekBar.max = music.duration; ? ? ? ?musicDuration.innerHTML = formatTime(music.duration); ? ?}, 300); ? ?currentMusicTime.innerHTML = '00 : 00'; ? ?queue.forEach(item => item.classList.remove('active')); ? ?queue[currentMusic].classList.add('active');}setMusic(0);
你可以注意到,為了設(shè)置持續(xù)時間,我們調(diào)用了formatTime,現(xiàn)在創(chuàng)建這個。
// 格式持續(xù)時間為 00 : 00 格式const formatTime = (time) => { ? ?let min = Math.floor(time / 60); ? ?if(min < 10){ ? ? ? ?min = `0` + min; ? ?} ? ?let sec = Math.floor(time % 60); ? ?if(sec < 10){ ? ? ? ?sec = `0` + sec; ? ?} ? ?return `${min} : ${sec}`;}
現(xiàn)在讓我們添加播放/暫停事件。
// playBtn 點擊事件playBtn.addEventListener('click', () => { ? ?music.play(); ? ?playBtn.classList.remove('active'); ? ?pauseBtn.classList.add('active');})// pauseBtn 點擊事件pauseBtn.addEventListener('click', () => { ? ?music.pause(); ? ?pauseBtn.classList.remove('active'); ? ?playBtn.classList.add('active');})
我們已經(jīng)完成了音樂的設(shè)置和播放/暫?!,F(xiàn)在進(jìn)行向前/向后事件。
// ?向前按鈕forwardBtn.addEventListener('click', () => { ? ?if(currentMusic >= songs.length - 1){ ? ? ? ?currentMusic = 0; ? ?} else{ ? ? ? ?currentMusic++; ? ?} ? ?setMusic(currentMusic); ? ?playBtn.click();})// 后退按鈕backwardBtn.addEventListener('click', () => { ? ?if(currentMusic <= 0){ ? ? ? ?currentMusic = songs.length - 1; ? ?} else{ ? ? ? ?currentMusic--; ? ?} ? ?setMusic(currentMusic); ? ?playBtn.click();})
快完成了,現(xiàn)在創(chuàng)建搜索欄功能。
// 搜索欄事件setInterval(() => { ? ?seekBar.value = music.currentTime; ? ?currentMusicTime.innerHTML = formatTime(music.currentTime); ? ?if(Math.floor(music.currentTime) == Math.floor(seekBar.max)){ ? ? ? ?if(repeatBtn.className.includes('active')){ ? ? ? ? ? ?setMusic(currentMusic); ? ? ? ? ? ?playBtn.click(); ? ? ? ?} else{ ? ? ? ? ? ?forwardBtn.click(); ? ? ? ?} ? ?}}, 500)seekBar.addEventListener('change', () => { ? ?music.currentTime = seekBar.value;})
做了這個之后。創(chuàng)建刷新功能和音量選項。
// 刷新按鈕repeatBtn.addEventListener('click', () => { ? ?repeatBtn.classList.toggle('active');})// 音量部分volumeBtn.addEventListener('click', () => { ? ?volumeBtn.classList.toggle('active'); ? ?volumeSlider.classList.toggle('active');})volumeSlider.addEventListener('input', () => { ? ?music.volume = volumeSlider.value;})
我們的播放器完成了。我們要做的最后一件事是使我們的播放列表正常運(yùn)行。
queue.forEach((item, i) => { ? ?item.addEventListener('click', () => { ? ? ? setMusic(i); ? ? ? ?playBtn.click(); ? ?})})
到這里我們已經(jīng)完成了所有代碼。播放器、導(dǎo)航欄、播放列表、輪播圖,刷新,音量加減等等
?? wuhu ! 起飛 !
希望通過本文,您已經(jīng)學(xué)會了如何使用 HTML、CSS 和 JS 的在線音樂播放器。我之前使用 HTML、CSS 和 JavaScript 制作了更多類型的小工具。
我已經(jīng)寫了很長一段時間的技術(shù)博客,并且主要通過CSDN發(fā)表,這是我的一篇 Web 在線音樂播放器教程。我喜歡通過文章分享技術(shù)與快樂。您可以訪問我的嗶哩嗶哩:?https://space.bilibili.com/63551025 以了解更多信息。希望你們會喜歡!??
?? 歡迎大家在評論區(qū)提出意見和建議!??
?? 完整源碼下載
如果你真的從這篇文章中學(xué)到了一些新東西,喜歡它,收藏它并與你的小伙伴分享。??最后,不要忘了?或??支持一下哦。
免費源碼可私信回復(fù)【音樂播放器】獲取