通过dispatchEvent实现代码的方式触发事件

背景介绍

在上一篇文章基于quill封装的富文本编辑器自定义工具栏全屏 - 掘金 (juejin.cn) 中有涉及到全屏的情况下,点击提交需要发送提交的请求且要关闭全屏,这时候就需要涉及到关闭全屏的代码逻辑。再拷贝一份同样的代码逻辑就太冗杂了。而使用dispatchEvent就可以完美的解决这个问题。下面就具体地来介绍下方法及使用案例

实现思路

  • 首先用Event 构造函数创建一个新的 Event 对象。
  • 然后,使用 dispatchEvent() 方法触发事件。

Event 构造函数

使用Event 构造函数来创建一个新事件:

js 复制代码
let event = new Event(type, [,options]);

Event 构造函数接受两个参数:(具体请看Event() - Web API 接口参考 | MDN (mozilla.org))

type

指定事件类型,比如click。或者表示所创建事件的名称

options

为对象类型,有两个属性:

  • bubbles:可选,布尔值类型,表示事件是否冒泡。如果为true,则事件冒泡,默认值为false
  • cancelable:可选,布尔值类型,表示事件是否可以取消,如果为true,则可以取消,默认值为false
  • composed,可选,布尔值类型,指示事件是否会在影子 DOM 根节点之外触发侦听器。默认值为 false,

下面我使用默认的options创建了一个点击事件

js 复制代码
let clickEvent = new Event('click');

UIEvent

UIEvent 是从 Event 派生出来的。包括MouseEvent, TouchEvent, FocusEvent, KeyboardEvent, WheelEvent, InputEvent, 和CompositionEvent。处理Event的一些属性,还提供了提供了更多特定于事件的信息。最好是最好使用 MouseEvent 这样的详细事件构造函数而不是通用的 Event 构造函数。

比如,MouseEvent 事件有许多其他属性,例如 clientX 和 clientY,它们指定事件发生时相对于视口的水平和垂直坐标:

js 复制代码
let clickEvent = new MouseEvent("click", {
  bubbles: true,
  cancelable: true,
  clientX: 150,
  clientY: 150
});

dispatchEvent

创建完事件后,我们就可以使用dispatchEvent() 方法在目标元素上触发它,像这样

csharp 复制代码
element.dispatchEvent(event);

下面就来测试一下:

html 复制代码
<button class="btn">测试dispatchEvent()方法</button>

<script>
  let btn = document.querySelector('.btn');

  btn.addEventListener('click', function () {
    alert('点击了');
  });

  let clickEvent = new Event('click');
  btn.dispatchEvent(clickEvent);
</script>

区分用户触发还是代码触发

通过event.isTrusted 来判断,如果事件来自用户操作则为true,如果事件由代码触发则为false

举个🌰

html 复制代码
<button class="btn1">按钮1</button>
<button class="btn2">按钮2</button>

<script>
  let btn1 = document.querySelector('.btn1')
  let btn2 = document.querySelector('.btn2')
  btn1.addEventListener('click', function (e) {
    console.log('我是按钮1')
    console.log(e.isTrusted)
  })
  btn2.addEventListener('click', function () {
    const event = new MouseEvent('click')
    // 调用了btn1绑定的click事件
    btn1.dispatchEvent(event)
    // console.log(event.isTrusted)
  })
</script>

在自定义全屏的实践使用

需求:实现在全屏状态下,点击确认提交按钮,退出全屏状态

实现:

.app-main为根节点class

js 复制代码
onConfirm () {
  // 拿到根节点
  const app = document.querySelector('.app-main')
  // 拿到自定义工具栏的设置全屏的节点
  const fullBtn = app.querySelector('.ql-fullScreen')
  // 全屏状态就退出全屏,全屏状态才有class(.show-full-screen)
  if (app && app.classList.contains('show-full-screen')) {
    // 调用自定义工具的click事件
    fullBtn && fullBtn.dispatchEvent(new MouseEvent('click'))
  }
}

总结

dispatchEvent可对某个节点的事件达到复用的作用,具体的用法:

js 复制代码
// 拿到class为btn的节点dom
const btn = document.querySelector('.btn')
btn.dispatchEvent(new MouseEvent('click'))
相关推荐
Hilaku2 分钟前
为什么我们用了 Vite 还是构建慢?——真正的优化在这几步
前端·javascript·vite
XI锐真的烦2 分钟前
横向对比npm和yarn
前端·npm·node.js
国家不保护废物3 分钟前
🧩 React 组件化进阶:像乐高大师一样搭建你的应用世界!
前端·react.js·ai编程
TimelessHaze10 分钟前
从"切图崽"到前端工程师:React 到底是个啥?🚀
前端·react.js·ai编程
站在风口的猪110814 分钟前
《前端面试题:CSS的display属性》
前端·css·html·css3·html5
wandongle15 分钟前
HTML 面试题错题总结与解析
前端·面试·html
Code_Geo17 分钟前
前端打包工具简单介绍
前端·打包工具
断竿散人21 分钟前
专题一、HTML5基础教程-Meta标签网页元数据:网页的隐形指挥官
前端