事件使用
監聽
dom.addEventListener(event, function)
event
事件類型
function
執行函數
let dom = document.querySelector('#dom');
dom.addEventListener('click', function(e) {
console.log(e);
});
e
事件氣泡,事件觸發時,系統自動傳遞
事件類型
click
點擊觸發
let btn = document.querySelector('#btn');
btn.addEventListener('click', function(e) {
console.log(e);
});
change
焦點移出時且數值變化時觸發,用於輸入類型元素(有 value
屬性)
let name = document.querySelector('#name');
name.addEventListener('change', function(e) {
console.log(name.value);
});
blur
焦點移出時觸發(focus
-> unfocus
)
let name = document.querySelector('#name');
name.addEventListener('blur', function(e) {
console.log(name.value);
});
與
chagne
類似,差別在於無論數值有沒有變化都會觸發
keypress
鍵盤按下時觸發
let name = document.querySelector('#name');
name.addEventListener('keypress', function(e) {
console.log(name.value);
});
keyup
鍵盤放開時觸發
let name = document.querySelector('#name');
name.addEventListener('keyup', function(e) {
console.log(name.value);
});
補充
keypress
與 keyup
產生的 e
事件物件會附帶觸發的按鍵
使用 e.key
可以取得觸發的按鍵
let name = document.querySelector('#name');
name.addEventListener('keyup', function(e) {
console.log(e.key);
});
練習
分數等級轉換
- 建立一個數字輸入匡
- 建立一個計算按鈕
- 當按下計算按鈕時,抓取數字輸入匡進行判斷
- 分數等級如下
>= 90 甲
>= 80 乙
>= 70 丙
>= 60 丁
< 60 不及格
- 數字輸入匡按下
enter
時,也可以進行計算
事件氣泡
事件監聽很好用,綁定都是針對單一元素處理,如果需要大量綁定,該如何處理?
html
<ul id="menu">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
點擊每一個 li
都印出當下 li
內容
js
let lis = document.querySelectorAll('#menu li')
lis.forEach(function (li) {
li.addEventListener('click', function (e) {
console.log(li.innerHTML)
})
})
問題
- 如果
li
有一萬個,會發生什麼事? - 如果透過事件去增加
li
,被新增的li
被點擊時是否也會印出自己內容?
html
<ul id="menu">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<button id="add-btn">add li</button>
js
let lis = document.querySelectorAll('#menu li')
lis.forEach(function (li) {
li.addEventListener('click', function (e) {
console.log(li.innerHTML)
})
})
let addBtn = document.querySelector('#add-btn')
addBtn.addEventListener('click', function (e) {
let menu = document.querySelector('#menu')
let li = document.createElement('li')
li.innerHTML = 'new li'
menu.appendChild(li)
})
觸發流程
先抓取,再冒泡

事件氣泡
了解事件觸發流程後,針對氣泡特性,改善先前 n
個 li
的事件綁定問題
let menu = document.querySelector('#menu')
menu.addEventListener('click', function (e) {
let li = e.target
console.log(li.innerHTML)
})
e.target
事件氣泡觸發元素
有沒有機會觸發到
ul
?
let menu = document.querySelector('#menu')
menu.addEventListener('click', function (e) {
let li = e.target
if (e.tagName == 'LI') {
console.log(li.innerHTML)
}
})
e.tagName
觸發元素標籤,統一為大寫
中斷冒泡
事件氣泡無論節點是否有處理,都會往上冒泡。如果不想氣泡繼續往上,使用 e.stopPropagation()
中斷冒泡
中斷預設行為
特定元素無需事件監聽就會進行預設行為,例如 a 元素會進行網頁跳轉。如想要禁止這種預設行為執行,使用 e.preventDefault()
中斷預設行為
html
<a href="https://www.google.com" id="link">Google</a>
let link = document.querySelector('#link')
link.addEventListener('click', function (e) {
e.preventDefault()
console.log(e.target.innerHTML)
})
單次計時器
在特定秒數後,執行特定函數,只執行一次
宣告
setTimeout(function, ms)
setTimeout(function() {
console.log('Run after 1000ms')
}, 1000)
1s = 1000ms
取消
clearTimeout(timer)
timer
為 setTimeout
回傳的計時器編號
let timer = setTimeout(function() {
console.log('Run after 1000ms')
}, 3000)
clearTimeout(timer)
重複計時器
在特定秒數後,執行特定函數,重複執行直到取消為止
宣告
setInterval(function, ms)
setInterval(function() {
console.log('Run after 1000ms')
}, 1000)
1s = 1000ms
取消
clearInterval(timer)
timer
為 setTimeout
回傳的計時器編號
let timer = setInterval(function() {
console.log('Run after 1000ms')
}, 3000)
clearInterval(timer)
練習
電子鐘

- 建立 UI
- 每秒更新該 UI 時間
時間取得方式
let d = new Date();
let hh = d.getHours();
let mm = d.getMinutes();
let ss = d.getSeconds();
綜合練習
TODO List

- 建立文字輸入匡,與一顆新增按鈕
- 建立列表區塊,每個項目前面加入 checkbox,如打勾則開項目顯示刪除線樣式。(
text-decoration: line-through;
) - 按下新增按鈕後,將目前文字輸入框內容新增至下方列表