JS 中的自定義事件和模擬事件

在 JS 中模擬事件指的是模擬 JS 中定義的一些事件,例如點擊事件,鍵盤事件等。

自定義事件指的是創建一個自定義的,JS 中之前沒有的事件。

接下來分別說一下創建這兩種事件的方法。

創建自定義事件

創建自定義事件可以使用 Event 和 CustomEvent 兩種方法,接下來分別做一下介紹。

1. 利用 Event

MDN Event

Event 用法

event = new Event(typeArg, eventInit);

typeArg:指定事件類型,傳遞一個字元串。這裡的事件類型指的是像點擊事件(click)、提交事件(submit)、載入事件(load)等等。

eventInit:可選,也可以以鍵值對的形式設置以下屬性。

  bubbles:事件是否支援冒泡,傳遞一個boolean類型的參數,默認值為false。

  cancelable:是否可取消事件的默認行為,傳遞一個boolean類型的參數,默認值為false。

  composed:事件是否會觸發shadow DOM(陰影DOM)根節點之外的事件監聽器,傳遞一個boolean類型的參數,默認值為false。

示例

  <section id="Event">
    <div id="root"></div>
    <script type="text/javascript">
      // 創建事件對象
      const newEvent = new Event('customType', { bubbles:true,cancelable:true,composed:true })
      // 獲取 DOM 元素
      const div = document.getElementById('root')
      // 綁定事件對象
      document.addEventListener('customType', () => {
        alert('自定式 customType 事件執行了')
      })
      // 觸發事件對象(真正開發中可以滿足某個條件後才觸發事件)
      div.dispatchEvent(newEvent)
    </script>
  </section>

2. 利用 CustomEvent

CustomEvent() 可以像 Event() 那樣使用,但它也可以在 Web Workers 中使用(與主執行緒分離的另一個執行緒),可以傳遞跟事件關聯的相關值(detail),detail 的默認值為null,類型為any(也就是說可以傳遞任意類型的參數),這個值就是和事件相關聯的值。

通過示例可以很明白地看出來兩者的區別。

  <section id="CustomEvent">
    <div id="root"></div>
    <script type="text/javascript">
      // 創建事件對象
      const newEvent = new CustomEvent('customType', { 
        bubbles:true,
        cancelable:true,
        composed:true,
        detail: {
          log: '我是 detail 屬性中的'
        }
      })
      // 獲取 DOM 元素
      const div = document.getElementById('root')
      // 綁定事件對象
      document.addEventListener('customType', () => {
        // 列印 event.detail.log 的值
        alert(`自定式 customType 事件執行了,${event.detail.log}`)
      })
      // 觸發事件對象(真正開發中可以滿足某個條件後才觸發事件)
      div.dispatchEvent(newEvent)
    </script>
  </section>

可以看到在 event 對象中會有 detail 屬性,我們可以輸出 detail 屬性中的內容。

創建模擬事件

想要模擬用戶的點擊等行為,可以通過模擬事件來實現。

步驟:

1)在 document 對象上使用 createEvent() 方法創建 event 對象,這個方法接收一個創建類型的字元串,主要有下面四種。

  • UIevents:一般化的 UI 事件,滑鼠和鍵盤事件都繼承自 UI 事件,DOM3 中是 UIEvent。
  • MouseEvents:滑鼠事件,DOM3 中是 MouseEvent。
  • MutationEvents:DOM 變動事件,DOM3 中是 MutationEvent。
  • HTMLEvents:HTML 事件。

使

2)初始化事件對象

在使用 document.createEvent() 創建出一個 event 對象之後,event 對象上會得到一個初始化的屬性,不同類型的 Event 對象屬性名不同,例如 MouseEvent 類型對應的屬性就是 initMouseEvent .

3)觸發事件

在實際開發中當滿足一定條件後我們可以使用 DOM元素.dispatchEvent(event) 來觸發事件。

接下來以模擬滑鼠點擊事件為例,說明一下上面的各個步驟。定義了一個 div 元素,綁定了一個 click 事件處理程式,內容是 alert('我不是用戶點擊的'),然後再模擬觸發 click 事件,可以發現即使在用戶不點擊時也可以彈出 '我不是用戶點擊的'.

  <section id="SimulateEvent">
    <div id="root"></div>
    <script type="text/javascript">
      // 獲取 DOM 元素
      const div = document.getElementById('root')
      // 綁定事件處理程式
      div.addEventListener('click', () => {
        alert('我不是用戶點擊的')
      }, false)
      // 創建滑鼠事件對象
      const event = document.createEvent('MouseEvents')
      // 初始化事件對象
      event.initMouseEvent('click', true, true, document.defaultView)
      // 觸發事件對象(真正開發中可以滿足某個條件後才觸發事件)
      div.dispatchEvent(event)
    </script>
  </section>

從上面的結果可以看到,即使我們沒有點擊 div 元素,它也會執行綁定的 click 的事件處理程式,原因就在於我們通過程式模擬了點擊事件。