JavaScript 创建自定义事件

javascript

JavaScript 创建自定义事件

除了让用户与浏览器交互触发生成事件,还可以使用 JavaScript 生成事件,而且还可以自定义事件的类型(不仅仅是浏览器内建事件类型。

事件构造器

内建事件类形成一个层次结构 hierarchy,类似于 DOM 节点类,其根是内建的 Event 类,还有一些具有特殊属性的内建事件类,如 UIEventFocusEventMouseEventWheelEventKeyboardEvent 等,通过这些类(事件构造器)可以构建新的事件对象

js
let event = new Event(type[, options]);
Announce

参数说明

  • type 事件类型,字符串形式,如点击事件类型 "click" 的字符串,也可以是自定义 "my-event" 的参数
  • options 具有两个可选属性的对象,默认情况下两者都为 false{bubbles: false, cancelable: false}
    • bubbles: true/false 如果为 true,那么事件会冒泡
    • cancelable: true/false 如果为 true,那么“默认行为”就会被阻止。稍后我们会看到对于自定义事件,它意味着什么。
Tip

对于内建的 UI 事件 有相应构造器创建相应类型的事件,推荐使用这些构造器创建事件对象,因为它们允许添加指定标准属性(而使用通用的 Event 构造器是不允许添加额外的信息的)。

js
// 创建一个 MouseEvent 鼠标交互事件
let event = new MouseEvent("click", {
  bubbles: true,
  cancelable: true,
  clientX: 100,   // 允许设置鼠标指针在点击元素(DOM)中的X坐标
  clientY: 100   // 允许设置鼠标指针在点击元素(DOM)中的Y坐标
});

alert(event.clientX); // 100

分配事件

事件对象被创建后应该使用 elem.dispatchEvent(event) 在特性的元素上「运行」它,然后处理程序会对它做出反应,就好像它是一个常规的(由用户交互触发的)浏览器事件一样。

html
<button id="elem" onclick="alert('Click!');">Autoclick</button>

<script>
  // 创建事件对象
  let event = new Event("click");
  // 分配事件,类似于程序自动模拟触发了 click 事件的发生
  elem.dispatchEvent(event);
</script>
Tip

可以使用事件对象属性 event.isTrusted 判断事件是否由自真实用户操作触发的,如果属性为 true表示事件由用户触发;如果属性为 false 表示事件由脚本生成。

自定义事件

可以使用通用事件 Event 构造器创建事件对象,但推荐使用构造器 new CustomEvent 创建自定义事件,该事件类明确地「标注」了创建的事件类型为自定义事件。

从技术上讲 CustomEventEvent 一样,但它提供了第二个参数(对象类型),具有特殊的 detail 字段/属性以传递任何自定义的信息,我们可以通过 event.detail 来访问这些信息。

html
<h1 id="elem">Hello for John!</h1>

<script>
  // 事件附带给处理程序的其他详细信息
  elem.addEventListener("hello", function(event) {
    alert(event.detail.name);
  });

  elem.dispatchEvent(new CustomEvent("hello", {
    detail: { name: "John" }
  }));
</script>
Warning

当我们需要为自定义事件设置监听器时,应该使用方法 elem。addEventListener,因为 on<event> 仅存在于内建事件中,如 document.onhello 是无法运行的。

event.preventDefault

对于自定义的事件没有默认的浏览器行为,但是此类事件的代码可能有自己的计划,即触发该事件之后会执行相应的操作,类似于内建事件,自定义事件也可以调用方法 event.preventDefault() 向系统发出一个信号,如果调用了该方法分配方法 elem.dispatchEvent(event) 就会返回 false,可以基于该信号进行条件判断以取消相应的行为。

html
<pre id="rabbit">
  |\   /|
   \|_|/
   /. .\
  =\_Y_/=
   {>o<}
</pre>

<!-- 监听 button 元素上的 click 事件,并触发 hide 处理程序 -->
<button onclick="hide()">Hide()</button>

<script>
  // button 点击事件的处理程序 hide
  function hide() {
    // 创建一个自定义名称为 hide 的事件
    let event = new CustomEvent("hide", {
      cancelable: true // 没有这个标志,preventDefault 将不起作用
    });

    //将 hide 事件分配给 rabbit 元素,并基于事件是否被阻止,返回 true/false
    if (!rabbit.dispatchEvent(event)) {
      alert('The action was prevented by a handler');
    } else {
      rabbit.hidden = true;
    }
  }

  // 在 rabbit 元素上监听 hide 事件
  rabbit.addEventListener('hide', function(event) {
    // hide 事件触发的处理程序,询问用户是否阻止「默认」行为
    if (confirm("Call preventDefault?")) {
      event.preventDefault();
    }
  });
</script>

上述代码实例演示了基于用户控制决定是否隐藏的兔子(字符串)的过程,我们在该元素上分派了 "hide" 事件,并在该元素上监听该事件,基于用户的选择决定是否使用 event.preventDefault() 来取消隐藏行为。


Copyright © 2024 Ben

Theme BlogiNote

Icons from Icônes