Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
JavaScirpt30 是 Wes Bos 推出的一個(gè) 30 天挑戰(zhàn)。項(xiàng)目免費(fèi)提供了 30 個(gè)視頻教程、30 個(gè)挑戰(zhàn)的起始文檔和 30 個(gè)挑戰(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 音樂鼓
模擬一個(gè)音樂鼓的效果。當(dāng)用戶按下 ASDFGHJKL 這幾個(gè)鍵時(shí),頁面上與字母對(duì)應(yīng)的元素變大,邊框變色(動(dòng)畫效果),播放對(duì)應(yīng)的音樂。
來一張效果圖:
打開index-START.html文件:
知識(shí)點(diǎn)分析:
頁面html中的數(shù)據(jù)屬性(data-xxx)
鍵盤事件處理
根據(jù)數(shù)據(jù)屬性選擇相對(duì)應(yīng)的元素
播放聲音
樣式修改
添加鍵盤事件監(jiān)聽。在windows上添加keydown事件。
keydown事件回調(diào)處理邏輯
(1)獲取對(duì)應(yīng)事件的keyCode
(2) 使用querySelector查找對(duì)應(yīng)data-key=keyCode的元素
(3)處理元素,播放音頻,添加樣式
div.key添加動(dòng)畫結(jié)束transitionened事件處理來處理動(dòng)畫結(jié)束后的樣式還原
ES6 中const 聲明只讀常量。
`${變量}`: 模板字面量(Template literals)。注意用反引號(hào),變量用${}
forEach 與箭頭函數(shù)
每次播放音效之后,需設(shè)置播放時(shí)間為0。
主要處理:重復(fù)按鍵。
動(dòng)事結(jié)束后需要移除樣式。
關(guān)注“教授學(xué)苑”,期待帶給你快樂的開發(fā)知識(shí).
款UI界面非常簡(jiǎn)潔美觀的html5小型網(wǎng)頁mp3音樂播放器開發(fā),暫停播放、歌曲切換、進(jìn)度條等基本功能都有。
<!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>
大家需要這個(gè)項(xiàng)目css代碼,js,圖片做練習(xí)的可以找我免費(fèi)領(lǐng)取,如果大家不怕麻煩可以關(guān)注我后私信我“前端學(xué)習(xí)資料”幾個(gè)字 找我領(lǐng)取 24小時(shí)在線!
節(jié)概覽:
這一章主要分享兩個(gè)東西,分別是進(jìn)度條和音軌。進(jìn)度條相對(duì)來說比較簡(jiǎn)單,于是先講。
這是上一次繪制好的音樂播放器,本節(jié)也在它的基礎(chǔ)上進(jìn)行完善。
對(duì)于進(jìn)度條,它可以實(shí)時(shí)地展示音樂的進(jìn)度,相信大家都不陌生。
1.繪制進(jìn)度條
我們?cè)诎粹o區(qū)的上面,也就是屏幕底部的區(qū)域繪制進(jìn)度條。
上代碼:
<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的部分就是我們需要添加的進(jìn)度條區(qū)域。
給它寬度、高度和背景色:
.music .screen .progress { width:100%; height:40px; background:#ccc; }
我們希望讓它緊挨著播放器屏幕的底部,只需要給它一個(gè)定位就行了。關(guān)于元素的定位,在之前的章節(jié)中我已經(jīng)詳細(xì)地講過,所以在這里就不再贅述了。
position: absolute; bottom:0;
下來了。
我們將該區(qū)域分為上下兩塊
.music .screen .progress .time { border-bottom:1px solid #fff; /*演示用,為了看清楚上下元素塊的界限*/ height:20px; /*高度為父盒子的一半*/ line-height:20px; /*為了讓文字垂直居中*/ text-align: right; /*文字右對(duì)齊*/ }
加上一個(gè)測(cè)試的時(shí)間數(shù)據(jù):
<div class='time'>1:30</div>
確認(rèn)沒問題后,把背景色和邊框都去掉。同時(shí)調(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; /*為了讓時(shí)間垂直居中*/ text-align: right; /*文字右對(duì)齊*/ padding-right: 10px; }
這樣就好看多了吧。
2.動(dòng)態(tài)獲取變化的時(shí)間
一步一步來,接下來我們先拿到正在播放的時(shí)間:
/** * 當(dāng)音頻時(shí)間正常更新的時(shí)候 */ musicBox.musicDom.ontimeupdate=function(){ var currentTime=Math.floor(this.currentTime); //獲取當(dāng)前時(shí)間 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你可以理解為一個(gè)監(jiān)聽事件,每次時(shí)間更新的時(shí)候,就會(huì)自動(dòng)進(jìn)入里面的邏輯。
在圖中可以很清晰地看到,我們已經(jīng)能拿到正在播放的時(shí)間了。
接下來,我們將這個(gè)動(dòng)態(tài)變化的時(shí)間在屏幕上顯示出來。
document.getElementsByClassName('time')[0].innerHTML=time;
嗯,這樣就行了。
2.計(jì)算百分比
// 百分比=當(dāng)前時(shí)長(zhǎng) ÷ 總時(shí)長(zhǎng) × 100% var total=this.duration;//總時(shí)長(zhǎng) console.log(currentTime + '=======' + total); document.getElementsByClassName('time')[0].innerHTML=Math.floor(currentTime / total * 100) + "%";
有了百分比,進(jìn)度條其實(shí)也就有了。我們現(xiàn)在將bar的樣式加上,寬度默認(rèn)0%
.music .screen .progress .bar { height:20px; background: #eee; width:0%; opacity: 0.6; }
然后動(dòng)態(tài)改變寬度:
var total=this.duration; document.getElementsByClassName('bar')[0].style.width=Math.floor(currentTime / total * 100) + "%";
成功了,進(jìn)度條就這么產(chǎn)生了。其中最關(guān)鍵的一點(diǎn)就是audio標(biāo)簽元素自帶的ontimeupdate 事件,我們可以在里面獲取總時(shí)長(zhǎng)和當(dāng)前時(shí)長(zhǎng),然后就可以計(jì)算出百分比,通過給div動(dòng)態(tài)設(shè)置寬度來實(shí)現(xiàn)進(jìn)度條的效果。
考慮到篇幅,我本章就不單獨(dú)封裝插件了,將進(jìn)度條集成到我們的musicBox里面,還需要用到回調(diào)函數(shù)等一系列的知識(shí)點(diǎn)。
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; }
我們希望音軌靠著下方,并且它們之間能有一個(gè)區(qū)分,于是添加這兩個(gè)屬性:
bottom:0px; border: 1px solid #ccc;
OK,下來了。
2. 畫所有的音軌
一個(gè)音軌肯定不夠,我們需要根據(jù)音軌盒子的寬度和每一條音軌的寬度,來計(jì)算出一共需要多少條音軌:
/*獲取音軌盒子*/ var trackBox=utils.dom('#trackBox'); /*音軌盒子的寬度*/ var maxWidth=trackBox.clientWidth; /*音軌的單個(gè)寬度*/ var singleWidth=10; /*計(jì)算音軌的最大數(shù)量*/ var len=Math.floor(maxWidth / singleWidth) ; alert('音軌盒子最多盛放' + len + '條音軌');
//拼接音軌 var tracks=""; for(var i=0;i < len; i++){ /*計(jì)算位置*/ var left=10 * i + 'px'; tracks +="<i class='items' style='left:"+left+"'></i>"; } trackBox.innerHTML=tracks;
拼接后的效果:
2. 通過隨機(jī)數(shù)讓音軌動(dòng)起來
之前的章節(jié) js常用方法和一些封裝(2) -- 隨機(jī)數(shù)生成 中,正好有一個(gè)隨機(jī)數(shù)的方法,所謂養(yǎng)兵千日,用兵一時(shí)啊。
我們把那個(gè)隨機(jī)數(shù)的方法添加到工具包:
util.js
randomNum : function (num){ return Math.floor(Math.random()*(num+1)); }
測(cè)試:
//模擬音軌動(dòng)畫 setInterval(function(){ for(var i=0;i < len; i++){ console.info(i); document.getElementsByClassName('items')[i].style.height=utils.randomNum(110) + 'px'; } },200);
效果:
原理就是用了一個(gè)js定時(shí)器,每隔200毫秒就改變所有音軌的高度,當(dāng)然,高度是一個(gè)隨機(jī)數(shù)值。
至于音軌和播放器的對(duì)接,雖然我已經(jīng)寫好,并且已經(jīng)集成到musicBox里面,但是里面牽扯到比較多的知識(shí)點(diǎn),寫起來需要很多時(shí)間,所以暫且先放一放吧。
音樂播放器至此算是完成了一個(gè)1.0版本,以后看情況我會(huì)繼續(xù)將這個(gè)案例更新下去,甚至還可能對(duì)接后臺(tái),連數(shù)據(jù)庫等等。
在工作的日子里,我曾經(jīng)迷茫過,尤其是剛開始做編程的工作時(shí),非常迷茫。
每天都是增刪改查,增刪改查,就覺得很沒意思。
一段時(shí)間下來,我開始迷茫了,不知道自己該學(xué)一些什么東西。
感覺技術(shù)太多,什么都想學(xué),卻又怕沒時(shí)間。
在這個(gè)信息爆炸、日新月異的時(shí)代,技術(shù)更新得非常快,很多人都在各種新技術(shù)的浪潮下變得不知所措。我就有這樣的體會(huì),于是看各種書,各種視頻,生怕自己跟不上時(shí)代的節(jié)奏。
可是,我一直以來都忽略了一個(gè)重點(diǎn),那就是——我是否真的對(duì)這個(gè)行業(yè)感興趣?
如果在幾年前,我會(huì)說是的,正因?yàn)閷?duì)計(jì)算機(jī)的興趣,我才會(huì)放棄之前所學(xué)的專業(yè),踏入 Java 、JavaScript 的坑中。
再后來,我發(fā)現(xiàn)一個(gè)道理,不論你現(xiàn)在的工作是什么,都請(qǐng)盡可能地去愛上他。不要為了生計(jì)而去做一份工作,如果實(shí)在辦不到的話,就給自己撒一個(gè)美麗的謊言吧。
不然的話,軟件開發(fā)到了后期你會(huì)很迷茫的。
給自己一個(gè)溫馨的微笑,學(xué)著熱愛這個(gè)行業(yè),這個(gè)工作,就是對(duì)自己最大的獎(jiǎng)賞。
享受編程的樂趣,懷著感恩的心去體會(huì)每一天生活中的細(xì)節(jié)。
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。