建立和觸發事件

本文演示如何建立和分派 DOM 事件。此類事件通常稱為**合成事件**,與瀏覽器本身觸發的事件相對。

建立自定義事件

可以使用 Event 建構函式建立事件,如下所示

js
const event = new Event("build");

// Listen for the event.
elem.addEventListener(
  "build",
  (e) => {
    /* … */
  },
  false,
);

// Dispatch the event.
elem.dispatchEvent(event);

以上程式碼示例使用了 EventTarget.dispatchEvent() 方法。

此建構函式在大多數現代瀏覽器中受支援。有關更詳細的方法,請參閱下面的 舊式方法

新增自定義資料 – CustomEvent()

要向事件物件新增更多資料,可以使用 CustomEvent 介面,並使用**detail**屬性傳遞自定義資料。例如,可以按如下方式建立事件

js
const event = new CustomEvent("build", { detail: elem.dataset.time });

然後,您可以在事件偵聽器中訪問這些附加資料

js
function eventHandler(e) {
  console.log(`The time is: ${e.detail}`);
}

舊式方法

建立事件的較舊方法使用受 Java 啟發的 API。以下顯示了一個使用 document.createEvent() 的示例

js
// Create the event.
const event = document.createEvent("Event");

// Define that the event name is 'build'.
event.initEvent("build", true, true);

// Listen for the event.
elem.addEventListener(
  "build",
  (e) => {
    // e.target matches elem
  },
  false,
);

// target can be any Element or other EventTarget.
elem.dispatchEvent(event);

事件冒泡

通常希望從子元素觸發事件,並讓祖先元素捕獲它;可以選擇性地攜帶資料

html
<form>
  <textarea></textarea>
</form>
js
const form = document.querySelector("form");
const textarea = document.querySelector("textarea");

// Create a new event, allow bubbling, and provide any data you want to pass to the "detail" property
const eventAwesome = new CustomEvent("awesome", {
  bubbles: true,
  detail: { text: () => textarea.value },
});

// The form element listens for the custom "awesome" event and then consoles the output of the passed text() method
form.addEventListener("awesome", (e) => console.log(e.detail.text()));

// As the user types, the textarea inside the form dispatches/triggers the event to fire, and uses itself as the starting point
textarea.addEventListener("input", (e) => e.target.dispatchEvent(eventAwesome));

動態建立和分派事件

元素可以偵聽尚未建立的事件

html
<form>
  <textarea></textarea>
</form>
js
const form = document.querySelector("form");
const textarea = document.querySelector("textarea");

form.addEventListener("awesome", (e) => console.log(e.detail.text()));

textarea.addEventListener("input", function () {
  // Create and dispatch/trigger an event on the fly
  // Note: Optionally, we've also leveraged the "function expression" (instead of the "arrow function expression") so "this" will represent the element
  this.dispatchEvent(
    new CustomEvent("awesome", {
      bubbles: true,
      detail: { text: () => textarea.value },
    }),
  );
});

觸發內建事件

此示例演示瞭如何使用 DOM 方法模擬對複選框的點選(即以程式設計方式生成點選事件)。檢視示例。

js
function simulateClick() {
  const event = new MouseEvent("click", {
    view: window,
    bubbles: true,
    cancelable: true,
  });
  const cb = document.getElementById("checkbox");
  const cancelled = !cb.dispatchEvent(event);

  if (cancelled) {
    // A handler called preventDefault.
    alert("cancelled");
  } else {
    // None of the handlers called preventDefault.
    alert("not cancelled");
  }
}

另請參閱