JavaScirpt30 是 Wes Bos 推出的一個 30 天挑戰(zhàn)。項目免費提供了 30 個視頻教程、30 個挑戰(zhàn)的起始文檔和 30 個挑戰(zhàn)解決方案源代碼。目的是幫助人們用純 JavaScript 來寫東西,不借助框架和庫,也不使用編譯器和引用。
官網(wǎng)的 slogan 如下:
Build 30 things in 30 days with 30 tutorial No Frameworks × No Compilers × No Libraries × No Boilerplate
現(xiàn)在你看到的是這系列指南的第 1 篇 - JavaScript 音樂鼓
模擬一個音樂鼓的效果。當(dāng)用戶按下 ASDFGHJKL 這幾個鍵時,頁面上與字母對應(yīng)的元素變大,邊框變色(動畫效果),播放對應(yīng)的音樂。
來一張效果圖:
打開index-START.html文件:
知識點分析:
頁面html中的數(shù)據(jù)屬性(data-xxx)
鍵盤事件處理
根據(jù)數(shù)據(jù)屬性選擇相對應(yīng)的元素
播放聲音
樣式修改
添加鍵盤事件監(jiān)聽。在windows上添加keydown事件。
keydown事件回調(diào)處理邏輯
(1)獲取對應(yīng)事件的keyCode
(2) 使用querySelector查找對應(yīng)data-key=keyCode的元素
(3)處理元素,播放音頻,添加樣式
div.key添加動畫結(jié)束transitionened事件處理來處理動畫結(jié)束后的樣式還原
ES6 中const 聲明只讀常量。
`${變量}`: 模板字面量(Template literals)。注意用反引號,變量用${}
forEach 與箭頭函數(shù)
每次播放音效之后,需設(shè)置播放時間為0。
主要處理:重復(fù)按鍵。
動事結(jié)束后需要移除樣式。
關(guān)注“教授學(xué)苑”,期待帶給你快樂的開發(fā)知識.
款UI界面非常簡潔美觀的html5小型網(wǎng)頁mp3音樂播放器開發(fā),暫停播放、歌曲切換、進度條等基本功能都有。
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>Music Player | Audio Player </title> <!--字體圖標(biāo)樣式--> <link rel='stylesheet' > <link rel='stylesheet' > <!--布局樣式--> <link rel="stylesheet" href="css/style.css"> </head> <body> <!-- Tracks used in this music/audio player application are free to use. I downloaded them from Soundcloud and NCS websites. I am not the owner of these tracks. Please don't create new pen by just copying and pasting code from this pen ( as I have seen some of them ), if you do that then don't forget to link back to this original pen. If you want to copy this pen then simply use the Fork button. Thank you --> <div id="app-cover"> <div id="bg-artwork"></div> <div id="bg-layer"></div> <div id="player"> <div id="player-track"> <div id="album-name"></div> <div id="track-name"></div> <div id="track-time"> <div id="current-time"></div> <div id="track-length"></div> </div> <div id="s-area"> <div id="ins-time"></div> <div id="s-hover"></div> <div id="seek-bar"></div> </div> </div> <div id="player-content"> <div id="album-art"> <img src="img/1.jpg" class="active" id="_1"> <img src="img/2.jpg" id="_2"> <img src="img/3.jpg" id="_3"> <img src="img/4.jpg" id="_4"> <img src="img/5.jpg" id="_5"> <div id="buffer-box">緩沖…</div> </div> <div id="player-controls"> <div class="control"> <div class="button" id="play-previous"> <i class="fas fa-backward"></i> </div> </div> <div class="control"> <div class="button" id="play-pause-button"> <i class="fas fa-play"></i> </div> </div> <div class="control"> <div class="button" id="play-next"> <i class="fas fa-forward"></i> </div> </div> </div> </div> </div> </div> </body> </html>
大家需要這個項目css代碼,js,圖片做練習(xí)的可以找我免費領(lǐng)取,如果大家不怕麻煩可以關(guān)注我后私信我“前端學(xué)習(xí)資料”幾個字 找我領(lǐng)取 24小時在線!
節(jié)概覽:
這一章主要分享兩個東西,分別是進度條和音軌。進度條相對來說比較簡單,于是先講。
這是上一次繪制好的音樂播放器,本節(jié)也在它的基礎(chǔ)上進行完善。
對于進度條,它可以實時地展示音樂的進度,相信大家都不陌生。
1.繪制進度條
我們在按鈕區(qū)的上面,也就是屏幕底部的區(qū)域繪制進度條。
上代碼:
<body> <div id='music' class='music'> <div class='screen'> <i id='music-icon' class="iconfont icon-yinle"></i> <div class='progress'> <div class='time'></div> <div class='bar'></div> </div> </div> <div class='buttons'> <i id='prev' class="iconfont icon-icon"></i> <i id='play' class="iconfont icon-bofanganniu"></i> <i id='pause' class="iconfont icon-zanting" style="display:none"></i> <i id='next' class="iconfont icon-icon1"></i> </div> <span id='info' class='info'></span> </div> </body>
代碼中progress的部分就是我們需要添加的進度條區(qū)域。
給它寬度、高度和背景色:
.music .screen .progress { width:100%; height:40px; background:#ccc; }
我們希望讓它緊挨著播放器屏幕的底部,只需要給它一個定位就行了。關(guān)于元素的定位,在之前的章節(jié)中我已經(jīng)詳細地講過,所以在這里就不再贅述了。
position: absolute; bottom:0;
下來了。
我們將該區(qū)域分為上下兩塊
.music .screen .progress .time { border-bottom:1px solid #fff; /*演示用,為了看清楚上下元素塊的界限*/ height:20px; /*高度為父盒子的一半*/ line-height:20px; /*為了讓文字垂直居中*/ text-align: right; /*文字右對齊*/ }
加上一個測試的時間數(shù)據(jù):
<div class='time'>1:30</div>
確認沒問題后,把背景色和邊框都去掉。同時調(diào)色和優(yōu)化一下:
.music .screen .progress { width:100%; height:40px; position: absolute; bottom:0; } .music .screen .progress .time { color: #fff; height:20px; line-height:20px; /*為了讓時間垂直居中*/ text-align: right; /*文字右對齊*/ padding-right: 10px; }
這樣就好看多了吧。
2.動態(tài)獲取變化的時間
一步一步來,接下來我們先拿到正在播放的時間:
/** * 當(dāng)音頻時間正常更新的時候 */ musicBox.musicDom.ontimeupdate=function(){ var currentTime=Math.floor(this.currentTime); //獲取當(dāng)前時間 var m=parseInt(currentTime / 60);//分鐘 var s=parseInt(currentTime % 60);//秒鐘 var time=(m<10?("0"+m):m)+":"+(s<10?("0"+s):s); //格式化 console.log(time); //打印出來看看 }
ontimeupdate你可以理解為一個監(jiān)聽事件,每次時間更新的時候,就會自動進入里面的邏輯。
在圖中可以很清晰地看到,我們已經(jīng)能拿到正在播放的時間了。
接下來,我們將這個動態(tài)變化的時間在屏幕上顯示出來。
document.getElementsByClassName('time')[0].innerHTML=time;
嗯,這樣就行了。
2.計算百分比
// 百分比=當(dāng)前時長 ÷ 總時長 × 100% var total=this.duration;//總時長 console.log(currentTime + '=======' + total); document.getElementsByClassName('time')[0].innerHTML=Math.floor(currentTime / total * 100) + "%";
有了百分比,進度條其實也就有了。我們現(xiàn)在將bar的樣式加上,寬度默認0%
.music .screen .progress .bar { height:20px; background: #eee; width:0%; opacity: 0.6; }
然后動態(tài)改變寬度:
var total=this.duration; document.getElementsByClassName('bar')[0].style.width=Math.floor(currentTime / total * 100) + "%";
成功了,進度條就這么產(chǎn)生了。其中最關(guān)鍵的一點就是audio標(biāo)簽元素自帶的ontimeupdate 事件,我們可以在里面獲取總時長和當(dāng)前時長,然后就可以計算出百分比,通過給div動態(tài)設(shè)置寬度來實現(xiàn)進度條的效果。
考慮到篇幅,我本章就不單獨封裝插件了,將進度條集成到我們的musicBox里面,還需要用到回調(diào)函數(shù)等一系列的知識點。
1. 繪制音軌盒子
<div id='music' class='music'> <div id='trackBox' class="trackBox"></div> <div class='screen'> <i id='music-icon' class="iconfont icon-yinle"></i> <div class='progress'> <div class='time'></div> <div class='bar'></div> </div> </div> <div class='buttons'> <i id='prev' class="iconfont icon-icon"></i> <i id='play' class="iconfont icon-bofanganniu"></i> <i id='pause' class="iconfont icon-zanting" style="display:none"></i> <i id='next' class="iconfont icon-icon1"></i> </div> <span id='info' class='info'></span> </div>
為了方便定位,我們將 trackBox 畫在music盒子里面。
.trackBox { position:absolute; width:400px; height:220px; border: 1px solid #ccc; z-index: 3; background: #333; left:210px; top : -2px; border-radius: 6px; }
2. 畫第一條音軌
<div id='trackBox' class="trackBox"> <i class='items'></i> </div> .trackBox .items { position: absolute; width:10px; height:100px; background:#eee; }
我們希望音軌靠著下方,并且它們之間能有一個區(qū)分,于是添加這兩個屬性:
bottom:0px; border: 1px solid #ccc;
OK,下來了。
2. 畫所有的音軌
一個音軌肯定不夠,我們需要根據(jù)音軌盒子的寬度和每一條音軌的寬度,來計算出一共需要多少條音軌:
/*獲取音軌盒子*/ var trackBox=utils.dom('#trackBox'); /*音軌盒子的寬度*/ var maxWidth=trackBox.clientWidth; /*音軌的單個寬度*/ var singleWidth=10; /*計算音軌的最大數(shù)量*/ var len=Math.floor(maxWidth / singleWidth) ; alert('音軌盒子最多盛放' + len + '條音軌');
//拼接音軌 var tracks=""; for(var i=0;i < len; i++){ /*計算位置*/ var left=10 * i + 'px'; tracks +="<i class='items' style='left:"+left+"'></i>"; } trackBox.innerHTML=tracks;
拼接后的效果:
2. 通過隨機數(shù)讓音軌動起來
之前的章節(jié) js常用方法和一些封裝(2) -- 隨機數(shù)生成 中,正好有一個隨機數(shù)的方法,所謂養(yǎng)兵千日,用兵一時啊。
我們把那個隨機數(shù)的方法添加到工具包:
util.js
randomNum : function (num){ return Math.floor(Math.random()*(num+1)); }
測試:
//模擬音軌動畫 setInterval(function(){ for(var i=0;i < len; i++){ console.info(i); document.getElementsByClassName('items')[i].style.height=utils.randomNum(110) + 'px'; } },200);
效果:
原理就是用了一個js定時器,每隔200毫秒就改變所有音軌的高度,當(dāng)然,高度是一個隨機數(shù)值。
至于音軌和播放器的對接,雖然我已經(jīng)寫好,并且已經(jīng)集成到musicBox里面,但是里面牽扯到比較多的知識點,寫起來需要很多時間,所以暫且先放一放吧。
音樂播放器至此算是完成了一個1.0版本,以后看情況我會繼續(xù)將這個案例更新下去,甚至還可能對接后臺,連數(shù)據(jù)庫等等。
在工作的日子里,我曾經(jīng)迷茫過,尤其是剛開始做編程的工作時,非常迷茫。
每天都是增刪改查,增刪改查,就覺得很沒意思。
一段時間下來,我開始迷茫了,不知道自己該學(xué)一些什么東西。
感覺技術(shù)太多,什么都想學(xué),卻又怕沒時間。
在這個信息爆炸、日新月異的時代,技術(shù)更新得非???,很多人都在各種新技術(shù)的浪潮下變得不知所措。我就有這樣的體會,于是看各種書,各種視頻,生怕自己跟不上時代的節(jié)奏。
可是,我一直以來都忽略了一個重點,那就是——我是否真的對這個行業(yè)感興趣?
如果在幾年前,我會說是的,正因為對計算機的興趣,我才會放棄之前所學(xué)的專業(yè),踏入 Java 、JavaScript 的坑中。
再后來,我發(fā)現(xiàn)一個道理,不論你現(xiàn)在的工作是什么,都請盡可能地去愛上他。不要為了生計而去做一份工作,如果實在辦不到的話,就給自己撒一個美麗的謊言吧。
不然的話,軟件開發(fā)到了后期你會很迷茫的。
給自己一個溫馨的微笑,學(xué)著熱愛這個行業(yè),這個工作,就是對自己最大的獎賞。
享受編程的樂趣,懷著感恩的心去體會每一天生活中的細節(jié)。
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。