通过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'))
相关推荐
houyhea1 天前
从香港竹脚手架到前端脚手架:那些"借来"的发展智慧与安全警示
前端
哈哈~haha1 天前
Step 14: Custom CSS and Theme Colors 自定义CSS类
前端·css·ui5
Ndmzi1 天前
Matlab编程技巧:自定义Simulink菜单(理解补充)
前端·javascript·python
勇气要爆发1 天前
物种起源—JavaScript原型链详解
开发语言·javascript·原型模式
我命由我123451 天前
VSCode - VSCode 修改文件树缩进
前端·ide·vscode·前端框架·编辑器·html·js
SoaringHeart1 天前
Flutter组件封装:验证码倒计时按钮 TimerButton
前端·flutter
San30.1 天前
深入理解 JavaScript OOP:从一个「就地编辑组件」看清封装、状态与原型链
开发语言·前端·javascript·ecmascript
AAA阿giao1 天前
JavaScript 原型与原型链:从零到精通的深度解析
前端·javascript·原型·原型模式·prototype·原型链
0***86331 天前
SQL Server2019安装步骤+使用+解决部分报错+卸载(超详细 附下载链接)
javascript·数据库·ui
烛阴1 天前
C#异常概念与try-catch入门
前端·c#