JS30 Day01
第一天就學到了很多語法與實際應用,是個收穫非常豐富的開始!:D


Javascript Drum Kit

完成目標

  • 功能
    • 按下鍵盤,出現相對應的聲音
  • 畫面
    • 按下鍵盤,畫面上的字母方塊,做點小動畫
      • 加上黃色陰影
      • 按鈕彈一下(微小放大)的動畫



index-START.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Drum Kit</title>
<link rel="stylesheet" href="style.css">
</head>
<body>


<div class="keys">
<div data-key="65" class="key">
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
<div data-key="83" class="key">
<kbd>S</kbd>
<span class="sound">hihat</span>
</div>
<div data-key="68" class="key">
<kbd>D</kbd>
<span class="sound">kick</span>
</div>
<div data-key="70" class="key">
<kbd>F</kbd>
<span class="sound">openhat</span>
</div>
<div data-key="71" class="key">
<kbd>G</kbd>
<span class="sound">boom</span>
</div>
<div data-key="72" class="key">
<kbd>H</kbd>
<span class="sound">ride</span>
</div>
<div data-key="74" class="key">
<kbd>J</kbd>
<span class="sound">snare</span>
</div>
<div data-key="75" class="key">
<kbd>K</kbd>
<span class="sound">tom</span>
</div>
<div data-key="76" class="key">
<kbd>L</kbd>
<span class="sound">tink</span>
</div>
</div>

<audio data-key="65" src="sounds/clap.wav"></audio>
<audio data-key="83" src="sounds/hihat.wav"></audio>
<audio data-key="68" src="sounds/kick.wav"></audio>
<audio data-key="70" src="sounds/openhat.wav"></audio>
<audio data-key="71" src="sounds/boom.wav"></audio>
<audio data-key="72" src="sounds/ride.wav"></audio>
<audio data-key="74" src="sounds/snare.wav"></audio>
<audio data-key="75" src="sounds/tom.wav"></audio>
<audio data-key="76" src="sounds/tink.wav"></audio>

<script>

</script>


</body>
</html>

style.css

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
html {
font-size: 10px;
background: url(http://i.imgur.com/b9r5sEL.jpg) bottom center;
background-size: cover;
}

body,
html {
margin: 0;
padding: 0;
font-family: sans-serif;
}

.keys {
display: flex;
flex: 1;
min-height: 100vh;
align-items: center;
justify-content: center;
}

.key {
border: 0.4rem solid black;
border-radius: 0.5rem;
margin: 1rem;
font-size: 1.5rem;
padding: 1rem 0.5rem;
transition: all 0.07s ease;
width: 10rem;
text-align: center;
color: white;
background: rgba(0, 0, 0, 0.4);
text-shadow: 0 0 0.5rem black;
}

.playing {
transform: scale(1.1);
border-color: #ffc600;
box-shadow: 0 0 1rem #ffc600;
}

kbd {
display: block;
font-size: 4rem;
}

.sound {
font-size: 1.2rem;
text-transform: uppercase;
letter-spacing: 0.1rem;
color: #ffc600;
}

音檔連結:https://reurl.cc/72y3N5


index-FINISHED.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Drum Kit</title>
<link rel="stylesheet" href="style.css">
</head>
<body>


<div class="keys">
<div data-key="65" class="key">
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
<div data-key="83" class="key">
<kbd>S</kbd>
<span class="sound">hihat</span>
</div>
<div data-key="68" class="key">
<kbd>D</kbd>
<span class="sound">kick</span>
</div>
<div data-key="70" class="key">
<kbd>F</kbd>
<span class="sound">openhat</span>
</div>
<div data-key="71" class="key">
<kbd>G</kbd>
<span class="sound">boom</span>
</div>
<div data-key="72" class="key">
<kbd>H</kbd>
<span class="sound">ride</span>
</div>
<div data-key="74" class="key">
<kbd>J</kbd>
<span class="sound">snare</span>
</div>
<div data-key="75" class="key">
<kbd>K</kbd>
<span class="sound">tom</span>
</div>
<div data-key="76" class="key">
<kbd>L</kbd>
<span class="sound">tink</span>
</div>
</div>

<audio data-key="65" src="sounds/clap.wav"></audio>
<audio data-key="83" src="sounds/hihat.wav"></audio>
<audio data-key="68" src="sounds/kick.wav"></audio>
<audio data-key="70" src="sounds/openhat.wav"></audio>
<audio data-key="71" src="sounds/boom.wav"></audio>
<audio data-key="72" src="sounds/ride.wav"></audio>
<audio data-key="74" src="sounds/snare.wav"></audio>
<audio data-key="75" src="sounds/tom.wav"></audio>
<audio data-key="76" src="sounds/tink.wav"></audio>

<script>
function removeTransition(e) {
if (e.propertyName !== 'transform') return;
e.target.classList.remove('playing');
}

function playSound(e) {
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
if (!audio) return;

key.classList.add('playing');
audio.currentTime = 0;
audio.play();
}

const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
window.addEventListener('keydown', playSound);
</script>


</body>
</html>



學習筆記


★ data-attribute

data-attribute 可以讓我們在 HTML 元素上嵌入自定義的屬性。

  • 屬性名稱不得包含任何大寫字母,並且前綴 “data-“ 後必須至少有一個字母
  • 屬性值可以是任何字串

*注意:前綴為”data-“的自定義屬性會被 User-Agent 完全忽略。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
<div class="block">
<p id="num01" data-number="no1" onclick="showMore(this)">1</p>
<p id="num02" data-number="no2" onclick="showMore(this)">2</p>
</div>

// 點擊後會跳出 data-attribute 的值
<script>
function showMore(number) {
var num = number.getAttribute("data-number");
alert("I'm" + num + ".");
}
</script>

★ < kbd > 標籤

< kbd > 標籤表示內容是使用者從鍵盤上輸入的,通常以等寬字體呈現。

1
<p>請輸入<kbd>ww</kbd>來表達開心。</p>

★ Arrow function

lambda 在 JavaScript 裡叫做 Arrow function(箭頭函式)。

  • 一般 js 的匿名函式這樣寫:
1
2
3
funtion (key) {
key.addEventListener('transitionend', removeTransition);
}
  • arrow function的寫法是:
1
key => key.addEventListener("transitionend", removeTransition);

*不同之處在於this,一般的寫法有this=function本身,但是「誰」呼叫arrow function,「誰」=this


★ keycode

keyCode 属性返回 onkeypress 事件觸發的 key 的值的字串,或 onkeydown 或 onkeyup 事件的 key 的代碼。

兩種代碼類型的區別:

  • 字串代碼:表示 ASCII 字符的數字
  • 鍵盤代碼 : 表示鍵盤上實際輸入的數字

*注意:which 和 keyCode 屬性解決瀏覽器兼容性的問題,但最新版本的 DOM 事件推薦使用 key 屬性。 which 和 keyCode 屬性不能用於 onkeypress 的非打印事件,功能鍵 (如 CAPS LOCK, CTRL, ESC, F12, 等)。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<input
type="text"
size="50"
onkeypress="uniCharCode(event)"
onkeydown="uniKeyCode(event)"
/>
<p>onkeypress - <span id="demo"></span></p>
<p>onkeydown - <span id="demo2"></span></p>

<script>
function uniCharCode(event) {
var char = event.which || event.keyCode; // 使用 which 或 keyCode, 以支援不同瀏覽器
document.getElementById("demo").innerHTML = " Unicode 字符代碼為: " + char;
}
function uniKeyCode(event) {
var key = event.keyCode;
document.getElementById("demo2").innerHTML = " Unicode 鍵代碼為: " + key;
}
</script>

★ Audio 播放方法

play() 方法播放音檔。

pause() 方法停止播放音檔。

範例:

1
2
3
4
5
6
7
8
9
var x = document.getElementById("myAudio");

function playAudio() {
x.play();
}

function pauseAudio() {
x.pause();
}

★ setTimeout()

setTimeout() 方法用於在指定的毫秒數後調用函式或計算表達式。

1
2
3
var timeoutID = scope.setTimeout(function[, delay, param1, param2, ...]);
var timeoutID = scope.setTimeout(function[, delay]);
var timeoutID = scope.setTimeout(code[, delay]);

*注意:setTimeout() 只會執行一次就結束,而 setInterval() 則是會在間隔固定的時間不斷重複。返回值 timeoutID是一個正整數,表示定時器的編號。這個值可以傳遞給 clearTimeout() 來取消該定時器。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
var timeoutID;

function delayedAlert() {
timeoutID = window.setTimeout(slowAlert, 2000);
}

function slowAlert() {
alert("That was really slow!");
}

function clearAlert() {
window.clearTimeout(timeoutID);
}

★ currentTime

currentTime 屬性設置或返回影音檔播放的當前位置(以秒計)。當設置該屬性時,播放會跳躍到指定的位置。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<audio id="myAudio" controls>
<source src="影音檔.mp3" type="audio/mpeg">
</audio>
<button onclick="getCurTime()" type="button">取得當前時間</button>
<button onclick="setCurTime()" type="button">設置時間為 1 秒 </button>
<script>
var x = document.getElementById("myAudio");
function getCurTime(){
alert(x.currentTime);
}
function setCurTime(){
x.currentTime = 1;
}
</script>