終於搞懂DOM事件!

導讀

  1. DOM事件綁定的幾種方式javascript

    • DOM元素上面綁定
    • js代碼匿名綁定
    • IE事件監聽綁定:attachEvent / detachEvent
    • 事件監聽綁定:addEventListener / removeEventListener
    • 兼容IE的事件監聽
  2. 事件流html

    • 事件流分爲哪幾個階段?
    • DOM事件流的發展
  3. 事件委託java

    • 什麼是事件委託
    • 事件委託的好處
    • jquery中的事件委託
    • 如何實現事件委託
  4. target 與 currentTarget的區別是什麼?node

🐑 DOM事件綁定的幾種方式

1.DOM元素上面綁定

<button onclick="btnClick1()" onclick="btnClick2()">click me</button>

<script> function btnClick1(){console.log('click!1')} function btnClick2(){console.log('click!2')} </script>
複製代碼

若是綁定了同一元素綁定了多個onclick 事件,那麼只會執行第一個。jquery

2.js代碼匿名綁定

btn.onclick = function(){console.log('1')}
btn.onclick = function(){console.log('2')}
複製代碼

若是是在js裏面匿名綁定的,那麼只會執行最後一個。chrome

3.IE事件監聽綁定:attachEvent / detachEvent

btn.attachEvent('onclick', function(){})
複製代碼

1.事件名,帶有onui

2.若是同一元素綁定了多個click 事件,都會執行,而且有前後順序。spa

3.注意:這個方法,chrome不支持,只有IE支持code

4.綁定了事件記得取消綁定,避免內存泄漏cdn

4.事件監聽綁定:addEventListener / removeEventListener

btn.addEventListener('click',function(){}, false) // 能夠區分捕獲階段 和 冒泡階段
複製代碼

1.事件名不帶on

2.若是綁定了同一元素綁定了多個click 事件,都會執行,而且有前後順序。

3.而且第三個參數的意思是是否開啓/使用事件捕獲階段,默認是false,就是默認是冒泡階段。

4.綁定了事件記得取消綁定,避免內存泄漏

5.兼容IE的事件監聽

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

DOM事件流的發展

其實剛開始DOM0的時候是隻有目標階段 和 冒泡階段的,直到出現了DOM2,才引進了捕獲階段。

1.DOM0

DOM0事件流只有兩個階段:目標階段 + 冒泡階段

btn.onclick = function(){

}
複製代碼

2.DOM2(IE不支持)

DOM2事件流只有3個階段:捕獲階段 + 目標階段 + 冒泡階段

那麼DOM2裏面如何區分捕獲階段和冒泡階段?

addEventListener 第二個參數的意思是,是否開啓事件捕獲。能夠區分,true 事件捕獲,默認是false 事件冒泡。

btn.addEventListener('click',function(){

}, true) // true 事件捕獲

btn.removeEvenetListener('click',function(){

}, false) // false 事件冒泡(默認)

複製代碼

🐑事件委託

什麼是事件委託

事件委託是,把本身元素的響應事件委託到其餘元素上面。通常是委託再父元素上。

事件委託的好處

1.減小內存的消耗

若是是一個列表,咱們給每一個列表項都綁定一樣的事件,是很是消耗內存的。

咱們能夠綁定到父組件列表上面,這樣能夠減小內存的消耗;

2.減小重複工做

咱們的列表項,若是刪除增長,都要重複進行一個操做就是刪除事件和綁定事件。

若是咱們綁定在父組件上面,咱們就能夠不用作這些重複的工做了。

jquery中的事件委託

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的區別是什麼?

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)//捕獲階段

複製代碼

1.當點擊c模塊的時候

捕獲階段:c(currentTarget)

目標階段:c (target)

冒泡階段:c(currentTarget)

2.當點擊b模塊的時候

捕獲階段:c

通過c模塊,觸發了c模塊的click事件,因此c模塊的currentTarget是c模塊,可是target仍是b模塊

目標階段:b

對於b模塊本身來講,target 和 currentTarget都是本身

冒泡階段:c

通過c模塊,觸發了c模塊的click事件,因此c模塊的currentTarget是c模塊,可是target仍是b模塊

點擊b模塊.jpg

3.當點擊a模塊的時候

捕獲階段: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模塊。

最後

相關文章
相關標籤/搜索