JavaScript 事件 (event)

addEventListener 監聽綁定

使用 addEventListener 方法來監聽 DOM 事件,語法如下:

1
2
3
4
5
6
7
8
addEventListener('event', function, true / false)
// 第三個參數可省略,預設為 false
// true (事件捕捉 - event capturing) - 從指定元素向外查找
// false (事件氣泡 - event bubbling) - 從指定元素向內查找

// 例子:
addEventListener('click', function() {
}, false)
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
<style>
.all {
height: 200px;
width: 200px;
background: red;
}
.box {
height: 100px;
width: 100px;
background: #000;
}
</style>

<h1>true</h1>
<div class="all">
<div class="box"></div>
</div>

<script>
var bodys = document.querySelector('.all');
var el = document.querySelector('.box');
el.addEventListener('click', function() {
console.log('box');
}, true); // 捕捉模式
bodys.addEventListener('click', function() {
console.log('body');
}, true);
</script>

Set addEventListener to true
Set addEventListener to false

stopPropagation - 中止冒泡事件

如果你希望阻止事件的冒泡,可以使用 stopPropagation() 方法:

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
<style>
.all {
height: 200px;
width: 200px;
background: red;
}
.box {
height: 100px;
width: 100px;
background: #000;
}
</style>

<h1>true</h1>
<div class="all">
<div class="box"></div>
</div>

<script>
var bodys = document.querySelector('.all');
var el = document.querySelector('.box');
el.addEventListener('click', function(e) {
e.stopPropagation(); // 中止冒泡事件
console.log('box');
}, false);
bodys.addEventListener('click', function() {
console.log('body');
}, false);
</script>

JavaScript stopPropagation

preventDefault - 取消預設觸發行為

可以使用 preventDefault() 方法來取消元素的預設行為:

1
2
3
4
5
6
7
8
<a href="https://tw.yahoo.com/" class="link">link</a>
<script>
var el = document.querySelector('.link');
el.addEventListener('click', function(e) {
e.preventDefault();
console.log('已取消連結');
});
</script>

JavaScript preventDefault

target - 了解當前元素位置

使用 e.target 來獲取當前事件目標:

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
<style>
.header {
background: pink;
}
.ul {
padding: 1rem;
}
li {
background: #fff;
padding: 1rem;
}
</style>

<header class="header">
<ul class="ul">
<li>123456789</li>
</ul>
</header>
<script>
var el = document.querySelector('.header');
el.addEventListener('click', function(e) {
console.log('target:', e.target);
console.log('nodeName:', e.target.nodeName);
});
</script>

JavaScript target

change - 表單內容變更時觸發

使用 change 事件來監聽表單的選擇變化:

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
<select name="area" id="area">
<option value="前鎮區">前鎮區</option>
<option value="苓雅區">苓雅區</option>
</select>
<ul class="list"></ul>

<script>
var area = document.getElementById('area');
var list = document.querySelector('.list');
var country = [
{ farmer: '查理', place: '前鎮區' },
{ farmer: '小花', place: '前鎮區' },
{ farmer: '大白', place: '苓雅區' },
];

function updatedList(e) {
var select = e.target.value;
var str = ''; // 組資料用
country.forEach(function(item) {
if (select === item.place) {
str += `<li>${item.farmer}</li>`;
}
});
list.innerHTML = str;
}

area.addEventListener('change', updatedList, false);
</script>

JavaScript change

keyCode - 鍵盤事件

監聽鍵盤事件並使用 keyCode 來判斷按鍵:

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
<style>
.list {
position: relative;
width: 100px;
height: 100px;
list-style-type: none;
background: pink;
}
.round {
position: absolute;
bottom: 0;
width: 25px;
height: 25px;
background: #000;
border-radius: 50%;
transition: 1s cubic-bezier(0.25, 0.1, 0.49, 0.16);
}
.round-1 {
left: 10px;
}
.round-2 {
left: 50%;
transform: translateX(-50%);
}
.round-3 {
right: 10px;
}
</style>

<ul class="list">
<li class="round round-1"></li>
<li class="round round-2"></li>
<li class="round round-3"></li>
</ul>

<script>
var body = document.body;
function keydown(e) {
switch (e.keyCode) {
case 49: // 1
document.querySelector('.round-1').style.bottom = '200px';
break;
case 50: // 2
document.querySelector('.round-2').style.bottom = '200px';
break;
case 51: // 3
document.querySelector('.round-3').style.bottom = '200px';
break;
}
}
body.addEventListener('keydown', keydown, false);
</script>

JavaScript keyCode

blur - 離開焦點時觸發事件

當 input 為空時顯示錯誤訊息:

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
<style>
input {
width: 50px;
}
.error {
display: none;
color: red;
}
.error.show {
display: block;
}
</style>

價目表:咖啡50元,蛋糕100元<br />
我要
<input type="text" class="input1" value="0"> 杯咖啡,
<input type="text" class="input2" value="0"> 份蛋糕
<button type="button" class="btn">計算</button>
<div class="error">數量錯誤</div><br />
總共 <span class="moneys">0</span>

<script>
var money = '';
var input1 = document.querySelector('.input1');
var input2 = document.querySelector('.input2');
var error = document.querySelector('.error');
var btn = document.querySelector('.btn');
var moneys = document.querySelector('.moneys');

function checkNum(e) {
if (e.target.value === '') {
error.classList.add('show');
} else {
error.classList.remove('show');
}
}

function checkMoney(e) {
if (input1.value !== '' && input2.value !== '') {
error.classList.remove('show');
money = input1.value * 50 + input2.value * 100;
} else {
error.classList.add('show');
money = 0;
}
moneys.textContent = money;
}

input1.addEventListener('blur', checkNum, false);
input2.addEventListener('blur', checkNum, false);
btn.addEventListener('click', checkMoney, false);
</script>

JavaScript blur

mouse - 當滑鼠滑入指定內容時觸發

監聽滑鼠移動事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<style>
.box {
width: 50px;
height: 50px;
background: #000;
}
</style>

<div class="box"></div>
<script>
var box = document.querySelector('.box');
function mousemove() {
console.log('mousemove start');
}
box.addEventListener('mousemove', mousemove, false);
</script>

JavaScript mouse

screen、page、client - 網頁座

標的差異

  • event.screenX, event.screenY:相對於整個螢幕的座標。
  • event.pageX, event.pageY:相對於整個網頁的座標。
  • event.clientX, event.clientY:相對於可視窗口的座標。

事件監聽優化 - 從父元素來監聽子元素

題目:點擊 li 顯示內容

範例一:querySelector 只取得第一個 li,因此點擊第二個會失效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
.list {
background: #989898;
padding: 50px;
}
</style>

<ul class="list">
<li>小白</li>
<li>阿花</li>
</ul>

<script>
var box = document.querySelector('.list li');
function listName(e) {
console.log(e.target.textContent);
}
box.addEventListener('click', listName, false);
</script>

JavaScript even Example 1

範例二:從父元素監聽,並過濾不必要的事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<style>
.list {
background: #989898;
padding: 50px;
}
</style>

<ul class="list">
<li>小白</li>
<li>阿花</li>
</ul>

<script>
var box = document.querySelector('.list');
function listName(e) {
if (e.target.nodeName !== "LI") return; // 重要過濾條件
console.log(e.target.textContent);
}
box.addEventListener('click', listName, false);
</script>

JavaScript even Example 2-1
JavaScript even Example 2-2