事件對象 事件對象是由瀏覽器在外面觸發事件的時候創建的,這個對象封裝了各種事件相關的各種信息 例如: 滑鼠的位置 鍵盤的按鍵 瀏覽器創建事件對象後,會將事件對象作為響應參數傳遞 在DOM類型中有多種不同類型的事件對象,但是他們都一個祖先Event event.clientX:獲取滑鼠的X軸坐標 ev ...
事件對象
事件對象是由瀏覽器在外面觸發事件的時候創建的,這個對象封裝了各種事件相關的各種信息
例如:
- 滑鼠的位置
- 鍵盤的按鍵
瀏覽器創建事件對象後,會將事件對象作為響應參數傳遞
在DOM類型中有多種不同類型的事件對象,但是他們都一個祖先Event
- event.clientX:獲取滑鼠的X軸坐標
- event.clientY:獲取滑鼠的Y軸坐標
- event.target:表示觸發事件的對象
- event.currentTarget:綁定事件的對象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>DOM</title>
<style>
.box1 {
width:300px;
height:300px;
background-color: #bfa;
}
</style>
</head>
<body>
<div id="box1" class="box1">
<div id="box2">
</div>
</div>
<script>
const box1 = document.getElementById("box1")
const box2 = document.getElementById("box2")
box1.onclick = function(event) {
console.log(event.target)
console.log(this)
}
box2.onclick = function(event) {
alert('我是box2')
}
</script>
</body>
</html>
事件冒泡
事件冒泡:當我們的元素上某個事件被觸發(內部元素不一定要綁定事件)後,其祖先元素的相同事件也會被觸發,冒泡大大的簡化了我們代碼的編寫,但是在某些場景下,我們有時也不希望冒泡
- event.stopPropagation():取消事件傳導
- event.preventDefault():取消事件的預設行為
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>DOM</title>
<style>
.box1 {
width:300px;
height:300px;
background-color: #bfa;
}
#box {
width:100px;
height:100px;
background-color: orange;
}
</style>
</head>
<body>
<div id="box1" class="box1">
<div id="box2">
</div>
</div>
<script>
const box1 = document.getElementById("box1")
const box2 = document.getElementById("box2")
box1.onclick = function(event) {
console.log(event.target)
console.log(this)
}
box2.onclick = function(event) {
// 停止box2點擊事件的傳導
event.stopPropagation()
alert('我是box2')
}
</script>
</body>
</html>
冒泡為什麼有利
當我們需要所有元素都有一個共有的事件時,我們如果沒有冒泡就需要一個個給他們添加事件
如果我們有冒泡,就只需要給它們的共同祖先元素添加一個事件就可以,這就是冒泡的好處
因為我們自己元素點擊之後,事件會向上冒泡,所以父級元素的處理器也會感知到
事件的委托
我們希望,只綁定一次事件,就可以讓所有的超鏈接和未來新添加的都具有這些事件
思路:我們可以將事件統一綁定document,這樣點擊超鏈接之後,由於事件的冒泡會導致document的事件被觸發,這樣就只綁定了一次,所有的超鏈接都會具有這些事件
但是這也帶來了一個問題,會讓除了超鏈接外的元素也觸發事件
委托
:就是本該綁定給多個對象的事件,綁定給它們的共同祖先元素,這樣就可以降低我們代碼的複雜度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>DOM</title>
</head>
<body>
<button type="button" id="btn">
點我一下
</button>
<ul id="list">
<li><a href="javascript:;">鏈接1</a></li>
<li><a href="javascript:;">鏈接2</a></li>
<li><a href="javascript:;">鏈接3</a></li>
<li><a href="javascript:;">鏈接4</a></li>
</ul>
<script>
const links = document.links;
const list = document.getElementById('list')
const btn = document.getElementById('btn')
for(let i = 0; i < links.length; i++) {
links[i].addEventListener('click',(event)=>{
alert(event.target.textContent)
})
}
// 點擊按鈕之後新添加一個li
/*
我們新添加的鏈接並不會綁定事件
*/
btn.addEventListener('click',()=>{
list.insertAdjancentHTML("beforeend","<li><a href="javascript:;">新鏈接</a><</li>")
})
</script>
</body>
</html>
處理委托帶來的問題
我們之前也說了問題的帶來的問題,我們在給共有父元素綁定事件的時候,只要是子元素都有可能觸發事件,那麼我們如果要選擇對應的子元素觸發事件呢?
可以用以下的方式來解決
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>DOM</title>
</head>
<body>
<button type="button" id="btn">
點我一下
</button>
<ul id="list">
<li><a href="javascript:;">鏈接1</a></li>
<li><a href="javascript:;">鏈接2</a></li>
<li><a href="javascript:;">鏈接3</a></li>
<li><a href="javascript:;">鏈接4</a></li>
</ul>
<script>
const list = document.getElementById('list')
const links = list.getElementByTagName('li');
const btn = document.getElementById('btn')
document.addEventListener("click",(event)=>{
if([...links].includes(event.target)){
alert('超鏈接事件對象觸發了')
}
})
// 點擊按鈕之後新添加一個li
/*
我們新添加的鏈接並不會綁定事件
*/
btn.addEventListener('click',()=>{
list.insertAdjancentHTML("beforeend","<li><a href="javascript:;">新鏈接</a><</li>")
})
</script>
</body>
</html>
這上面的代碼必須是li才能觸發事件,要不然是不能觸發事件的
事件的捕獲
在DOM中,事件的傳播分為三個階段
- 捕獲階段
- 事件的捕獲指的是我們的事件從外向內傳導
- 由祖先元素向目標元素進行事件的捕獲
- 目標階段(觸發事件的對象)
- 冒泡階段
- 由目標元素想祖先元素進行冒泡從內向外傳導
如果我們希望在捕獲階段觸發事件,那麼我們就需要將addEventListener()的第三個參數設置為true
註意:我們一般不希望在捕獲階段觸發事件,設置了捕獲事件,冒泡就會失效
- evnet.eventPhase:事件觸發的時機
- 0:表示沒有觸發事件
- 1:是捕獲階段
- 2:表示為目標階段
- 3:表示冒泡階段
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>DOM</title>
<style>
#box1 {
width:300px;
height:300px;
background-color:skyblue;
}
#box2 {
width:200px;
height:200px;
background-color:orange;
}
#box2 {
width:100px;
height:100px;
background-color:tomato;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3">
</div>
</div>
</div>
<script>
const box1 = document.getElemenetById("box1")
const box2 = document.getElemenetById("box2")
const box3 = document.getElemenetById("box3")
box1.addEventListener("click",(event)=>{
alert(1)
},true)
box2.addEventListener("click",(event)=>{
alert(2)
},true)
box3.addEventListener("click",(event)=>{
alert(3)
},true)
</script>
</body>
</html>