DOM Model

知識點:

  • Document Event
  • onlickaddEventListener 區別
  • 捕捉事件和泡沫事件
  • stopPropagation()

Document Event

DOM level 是由 W3C 提供規範
我只針對 click 事件描述

DOM level 0

  • onclick 可以在 htmljs去寫,但比較容易出錯(混亂)

DOM level 1

  • 並沒有對事件做什麼

DOM level 2

  • addEventListener
  • removeEventListener

onlick 和 addEventListener 區別

// 在 html 和 js 寫 onclick很容易混雜!
html
* 在 html 裡是需要執行的程式,而不是函數

<button onclick="x()">A</button> // 正確
<button onclick="x">A</button> // 錯

js
* 在 JS 裡是要函數,因為我們需要等待使用者點擊然後才調用!
* onclick 屬性是函數值.

function clickMe () {}
x.onlick = clickMe() // 錯
x.onlick = clickMe // 正確

// onlick 屬性,唯一
// 如果綁定兩個事件,就不行,會被覆蓋
x.onlick = function () {}
x.onlick = function () { // 會被覆蓋 }

// addEventListener 隊列(先進先出),
// 綁定兩個事件,會先進先出(1,2)。
// 先1進去,後1先出,
// 接下來 先2進去,後2先出。
// 會先把在 addEventListener 隊列裡存放兩個函數,
// 當我觸發 click 事件時,會執行隊列裡函數!

x.addEventListener('click', function () { // 1 })
x.addEventListener('click', function () { // 2 })

// 1,2進行排隊,但還沒被觸發1就離開了 -> 2
x.removeEventListener('click', function () { // 1 })
<!-- html -->
<div id="grand">
  爺爺
  <div id="father">
    爸爸
    <div id="child">
      兒子
    </div>
  </div>
</div>
/* css */
#grand {
  border: 1px solid blue;
  padding: 20px;
}

#father {
  border: 1px solid red;
  padding: 20px;
}

#child {
  border: 1px solid black;
  padding: 20px;
}
// JS
// 
// 爺爺,爸爸,兒子都在同一個範圍內
// 當我點擊兒子時,是否點擊了爸爸和爺爺 (血緣關係息息相關)
// -> yes

// 當我點擊兒子時,三個函數是否調用,
// -> yes 兒子,爸爸,爺爺。
// 在 addEventListener 第三參數:default false (由下到上[泡沫]),
// 但如果在第三參數設 true (由上到下[捕獲]) 誰先被執行。
// 主要是誰先執行問題

grand.addEventListener('click', function () {
  console.log('爺爺')
})

father.addEventListener('click', function () {
  console.log('爸爸')
})

child.addEventListener('click', function (e) {
  // stopPropagation 告訴不要告訴我爸爸和爺爺
  // 停止傳播,切斷關係
  // e.stopPropagation() 
  console.log('兒子')
})

// 面試題
// -> 捕獲,泡沫
// 如是同一個元素,會進行先進先出(隊列)
child.addEventListener('click', function () {
  console.log('兒子 捕獲')
}, true)

child.addEventListener('click', function () {
  console.log('兒子 泡沫')
}, false)