DOM事件綁定的幾種方式javascript
事件流html
事件委託java
target 與 currentTarget的區別是什麼?node
<button onclick="btnClick1()" onclick="btnClick2()">click me</button>
<script> function btnClick1(){console.log('click!1')} function btnClick2(){console.log('click!2')} </script>
複製代碼
若是綁定了同一元素綁定了多個onclick 事件,那麼只會執行第一個。jquery
btn.onclick = function(){console.log('1')}
btn.onclick = function(){console.log('2')}
複製代碼
若是是在js裏面匿名綁定的,那麼只會執行最後一個。chrome
btn.attachEvent('onclick', function(){})
複製代碼
1.事件名,帶有onui
2.若是同一元素綁定了多個click 事件,都會執行,而且有前後順序。spa
3.注意:這個方法,chrome不支持,只有IE支持code
4.綁定了事件記得取消綁定,避免內存泄漏cdn
btn.addEventListener('click',function(){}, false) // 能夠區分捕獲階段 和 冒泡階段
複製代碼
1.事件名不帶on
2.若是綁定了同一元素綁定了多個click 事件,都會執行,而且有前後順序。
3.而且第三個參數的意思是是否開啓/使用事件捕獲階段,默認是false,就是默認是冒泡階段。
4.綁定了事件記得取消綁定,避免內存泄漏
if (a.addEventListener) {
a.addEventListener('click', function(){
console.log('is addEventListener!')
})
} else if (a.attachEvent) {
a.attachEvent('onclick', function(){
console.log('is attachEvent!')
})
} else {
console.log('others')
}
複製代碼
1.捕獲階段:從上往下,document會先捕獲到,到html,body,...,直到觸發事件的那個元素
2.目標階段:觸發事件的那個元素
3.冒泡階段:從下往上,觸發事件的那個元素往父元素,...,到body,html,document
其實剛開始DOM0的時候是隻有目標階段 和 冒泡階段的,直到出現了DOM2,才引進了捕獲階段。
DOM0事件流只有兩個階段:目標階段 + 冒泡階段
btn.onclick = function(){
}
複製代碼
DOM2事件流只有3個階段:捕獲階段 + 目標階段 + 冒泡階段
addEventListener 第二個參數的意思是,是否開啓事件捕獲。能夠區分,true 事件捕獲,默認是false 事件冒泡。
btn.addEventListener('click',function(){
}, true) // true 事件捕獲
btn.removeEvenetListener('click',function(){
}, false) // false 事件冒泡(默認)
複製代碼
事件委託是,把本身元素的響應事件委託到其餘元素上面。通常是委託再父元素上。
1.減小內存的消耗
若是是一個列表,咱們給每一個列表項都綁定一樣的事件,是很是消耗內存的。
咱們能夠綁定到父組件列表上面,這樣能夠減小內存的消耗;
2.減小重複工做
咱們的列表項,若是刪除增長,都要重複進行一個操做就是刪除事件和綁定事件。
若是咱們綁定在父組件上面,咱們就能夠不用作這些重複的工做了。
on/delegate
事件委託通常是由 事件冒泡來實現的
案例🌰:使用addEventListener點擊li彈出內容,而且動態添加li以後有效
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
複製代碼
// 給父層元素綁定事件
document.getElementById('list').addEventListener('click', function (e) {
var target = event.target
if (target.nodeName.toLocaleLowerCase === 'li') {
console.log('the content is: ', target.innerHTML);
}
});
複製代碼
target指的是目標階段。
currentTarget指的是捕獲階段,目標階段 和 冒泡階段。(通常指目標元素的父級)
<div id="c">c
<div id="b">b
<div id="a">a</div>
</div>
</div>
複製代碼
const b = document.getElementById('b');
const a = document.getElementById('a');
const c = document.getElementById('c');
b.addEventListener('click', (e)=>{
console.log("click b=>", "target:",e.target, "currentTarget:",e.currentTarget)
})
//b.addEventListener('click', (e)=>{
// console.log("click b=>", "target:",e.target, "currentTarget:",e.currentTarget)
//},true) //捕獲階段
a.addEventListener('click',(e)=>{
console.log("click a=>", "target:",e.target, "currentTarget:",e.currentTarget)
})
//a.addEventListener('click',(e)=>{
// console.log("click a=>", "target:",e.target, "currentTarget:",e.currentTarget)
//},true) //捕獲階段
c.addEventListener('click',(e)=>{
console.log("click c=>", "target:",e.target, "currentTarget:",e.currentTarget)
})
//c.addEventListener('click',(e)=>{
// console.log("click c=>", "target:",e.target, "currentTarget:",e.currentTarget)
//},true)//捕獲階段
複製代碼
捕獲階段:c(currentTarget)
目標階段:c (target)
冒泡階段:c(currentTarget)
捕獲階段:c
通過c模塊,觸發了c模塊的click事件,因此c模塊的currentTarget是c模塊,可是target仍是b模塊
目標階段:b
對於b模塊本身來講,target 和 currentTarget都是本身
冒泡階段:c
通過c模塊,觸發了c模塊的click事件,因此c模塊的currentTarget是c模塊,可是target仍是b模塊
點擊b模塊.jpg
捕獲階段:c -- b
通過了c模塊和b模塊,因此觸發了c,b模塊的點擊事件。對於c模塊來講,currentTarget就是c模塊,target仍是a模塊。對於b模塊來講,currentTarget就是b模塊,target仍是a模塊。
目標階段:a
對於a模塊本身來講,target 和 currentTarget都是本身
冒泡階段:b --- c
通過了c模塊和b模塊,因此觸發了c,b模塊的點擊事件。對於c模塊來講,currentTarget就是c模塊,target仍是a模塊。對於b模塊來講,currentTarget就是b模塊,target仍是a模塊。