vue3-创建/监听/触发事件(Event/dispatchEvent)

740 阅读5分钟

创建和触发事件

本文演示了如何创建和分派 DOM 事件。这些事件通常称为合成事件,而不是浏览器本身触发的事件。

创建自定义事件

可以使用 Event 构造函数创建事件,如下所示:

const event = new Event("build");

// 监听该事件。
elem.addEventListener(
  "build",
  (e) => {
    /* … */
  },
  false,
);

// 分派该事件。
elem.dispatchEvent(event);

上述代码使用了 EventTarget.dispatchEvent() 方法。

绝大多数现代浏览器中都支持这个构造函数。要了解更为复杂的方法,可参考下面的过时的方式

添加自定义数据——CustomEvent()

要向事件对象添加更多数据,可以使用 CustomEvent 接口,detail 属性可用于传递自定义数据。 例如,可以像这样创建事件:

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

下面的代码允许你在事件监听器中访问更多的数据:

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

过时的方式

早期的创建事件的方法使用了受 Java 启发的 API。下面是一个使用 document.createEvent() 的示例:

// 创建事件。
const event = document.createEvent("Event");

// 定义事件的名称为“build”。
event.initEvent("build", true, true);

// 监听该事件。
elem.addEventListener(
  "build",
  (e) => {
    // e.target 与 elem 相匹配
  },
  false,
);

// 目标(target)可以是任何元素或其他 EventTarget。
elem.dispatchEvent(event);

事件冒泡

通常需要从子元素触发事件,并让其祖先捕获它;且可以带有数据:

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

// 创建一个新事件,允许冒泡,并提供要传递给“detail”属性的任何数据
const eventAwesome = new CustomEvent("awesome", {
  bubbles: true,
  detail: { text: () => textarea.value },
});

// 表单(form)元素监听自定义的“awesome”事件,然后在控制台打印传递的 text() 方法的输出
form.addEventListener("awesome", (e) => console.log(e.detail.text()));

// 当用户输入时,表单中的文本区域会分派/触发事件,并以自身为事件的起点
textarea.addEventListener("input", (e) => e.target.dispatchEvent(eventAwesome));

动态创建和分派事件

元素可以监听尚未创建的事件:

HTMLCopy to Clipboard

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

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

textarea.addEventListener("input", function () {
  // 动态创建并分派/触发一个事件
  // 注意:我们还可以使用“函数表达式”(而不是“箭头函数表达式”),这样“this”将表示该元素
  this.dispatchEvent(
    new CustomEvent("awesome", {
      bubbles: true,
      detail: { text: () => textarea.value },
    }),
  );
});

触发内置事件

下面的示例演示了使用 DOM 方法在复选框上模拟点击(click)(即,通过编程方法生成 click 事件)。参见这个动态示例。

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) {
    // 处理器调用了 preventDefault。
    alert("cancelled");
  } else {
    // 没有处理器调用 preventDefault。
    alert("not cancelled");
  }
}

dispatchEvent使用方法

dispatchEvent 是 JavaScript 中用于触发事件的方法。它可以在指定的元素上分派一个自定义的事件。

使用 dispatchEvent 方法时,你需要创建一个事件对象,并将其分派到目标元素上。以下是 dispatchEvent 的基本用法:

element.dispatchEvent(event);

其中,element 是要分派事件的目标元素,event 是要分派的事件对象。

要创建一个事件对象,你可以使用 Event 构造函数或其子类构造函数。以下是创建事件对象的示例代码:

const event = new Event(type, options);

其中,type 是事件类型,例如 'click''keydown' 等。options 是一个可选的配置对象,用于指定事件的属性,例如 bubbles(是否冒泡)、cancelable(是否可取消)等。

以下是一个示例,演示如何使用 dispatchEvent 方法触发一个自定义的点击事件:

const myButton = document.querySelector('#myButton');

const clickEvent = new Event('click', { bubbles: true });
myButton.dispatchEvent(clickEvent);

在上述代码中,我们首先选择了一个具有 id'myButton' 的按钮元素。然后,我们创建了一个自定义的点击事件对象 clickEvent,并使用 dispatchEvent 方法将其分派到按钮元素上。

这样,按钮元素将触发一次点击事件。

需要注意的是,dispatchEvent 方法只能触发已注册的事件处理程序。如果你想模拟用户的点击行为,确保目标元素上已绑定了相应的事件处理程序。

new Event和document.createEvent方法的区别

在创建事件对象时,可以使用两种不同的方法:new Eventdocument.createEvent。它们之间的区别在于以下几个方面:

  1. 语法:new Event 是使用构造函数创建事件对象,而 document.createEvent 是使用 createEvent 方法创建事件对象。
  2. 兼容性:new Event 是较新的方法,它在现代浏览器中得到广泛支持。而 document.createEvent 是旧的方法,它在较旧的浏览器中仍然可以使用,但在一些现代浏览器中已被废弃。
  3. 事件类型:new Event 可以创建任何类型的事件对象,例如 'click''keydown' 等。而 document.createEvent 需要根据具体的事件类型使用不同的方法,例如 createEvent('Event')createEvent('MouseEvent') 等。
  4. 事件属性:new Event 创建的事件对象是一个普通的 Event 对象,它没有特定的属性。而 document.createEvent 创建的事件对象是一个具有特定属性的特定事件类型对象,例如 MouseEventKeyboardEvent 等,可以设置更多的事件属性,如鼠标坐标、键盘按键等。

综上所述,如果你的目标是创建一个普通的事件对象,可以使用较新的 new Event 方法。如果你需要创建一个特定类型的事件对象,并设置更多的事件属性,可以使用 document.createEvent 方法。

然而,需要注意的是,随着浏览器的发展,new Event 方法已成为主流,而 document.createEvent 方法逐渐被废弃。因此,建议在现代浏览器中优先使用 new Event 方法来创建事件对象。