1. 程式人生 > 其它 >JS基礎總結 - 事件委託和事件繫結函式

JS基礎總結 - 事件委託和事件繫結函式

目錄

1. 事件繫結


1.1 示例:

const div1 = document.getElementById('div1')
div1.addEventListener('click', e => {
  console.log('clicked')
})

1.2 事件繫結函式

在實際開發中,經常需要為元素繫結事件。因此可以將事件繫結的程式碼封裝成一個通用的事件繫結函式。(如下 ↓)

// 事件繫結函式1.0版 (不支援事件代理)
function bindEvent(elem, type, fn) {
  elem.addEventListener(type, fn)
}

// 測試
const btn = document.getElementById('btn1')
bindEvent(btn, 'click', e => {
  // console.log(e.target) // 獲取觸發的元素
  // e.preventDefault() // 阻止預設行為
  // e.stopPropagation() // 阻止事件冒泡
  console.log('clicked')
})


2. 事件委託 / 代理

利用事件的冒泡機制,我們可以在父級元素上繫結事件,從而監聽子元素上冒泡上來的事件。


2.1 示例

const div1 = document.getElementById('div1')
div1.addEventListener('click', e => {
  const target = e.target
  if (target.nodeName === 'A') {
    console.log(target.innerHTML)
  }
})

2.2 事件委託的優點

  • 程式碼更簡潔。
  • 效能更好。只繫結一次事件,減少記憶體的使用。

2.3 改寫事件繫結函式(相容事件委託)

// 事件繫結函式2.0 (支援事件代理)
function bindEvent(elem, type, selector, fn) {
  if (fn == null) {
    fn = selector
    selector = null
  }
  elem.addEventListener(type, e => {
    const target = e.target
    if (selector) { // 代理繫結
      if (target.matches(selector)) { // 元素能否被指定的選擇器字串選擇
        fn.call(target, e)
      }
    } else { // 普通繫結
      fn.call(target, e)
    }
  })
}

// 測試
const div1 = document.getElementById('div1')
bindEvent(div1, 'click', 'a', e => {
  e.preventDefault()
  alert(this.innerHTML)
})