怎么创建 JavaScript 自定义事件

更新日期: 2022-04-29阅读: 958标签: 事件

你肯定处理过很多的事件监听,比如点击事件或者表单提交。事件监听对许多用例来说很有帮助,但是有时我们需要创建自己的自定义事件来处理复杂的交互。在这片短文中,我将告诉你有关创建自定义事件,侦听自定义事件以及创建双击自定义事件所要了解的内容。

怎么创建自定义事件

创建自定义事件听起来很困难,但是只需要下面简单的一行代码即可。

const myEvent = new Event("myCustomEvent")

你可以通过事件构造函数创建一个新的 Event 对象。在最基本的形式中,你只需要将一个字符串传递给构造函数,这个字符串就是你定义的事件名称。为了监听这个事件,你可以将该事件监听器添加到你要监听的元素上,如下:

document.addEventListener("myCustomEvent", e => {
  console.log(e)
})

最后一步,你需要做的事,触发创建并正在监听的事件。

document.dispatchEvent(myEvent)

这就需呀 dispatchEvent 函数了。每个元素都有这个方法,你要做的就是将你创建的对象传递给它。

如果我们将上面讲的组合在一起,我们就得到了一个基本的事件,这个事件在我们的 document 元素触发,相关的事件内容会被打印出来。

{
isTrusted: false
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: null
defaultPrevented: false
eventPhase: 0
path: [document, window]
returnValue: true
srcElement: document
target: document
timeStamp: 54.69999998807907
type: "myCustomEvent"
}

图中是这个事件对象的最基本形式。它包含大量信息,最重要的部分我这里突出显示了。

isTrusted 属性仅指该事件是由用户交互触发,还是由自定义 JavaScript 代码触发的。例如,当用户单击按钮时,事件将 isTrusted 设置为 true,而我们自定义的事件会将其设置为 false,因为该事件是由 JavaScript 触发的。

target 指调用 dispatchEvent 函数的元素。

type 指事件的名称。

事件定制

你可能注意到了,上面的详情中有属性 bubbles, cancelable 和 composed 属性。这些实际上,在我们创建自定义事件时可以配置的选项。

const myEvent = new Event("myCustomEvent", {
  bubbles: true,
  cancelable: true,
  composed: true
})

冒泡 bubbles

当事件触发后,bubbles 属性决定这个事件是否可以通过 html 进行冒泡。这个值默认为 false,这意味着不可以进行冒泡行为,如果你想事件调用父 HTML 元素,你可以将其设置为 true。

const bubbleEvent = new Event("bubbleEvent", { bubbles: true })
const defaultEvent = new Event("defaultEvent", { bubbles: false })

document.addEventListener("bubbleEvent", () => {
  // This will get called since the event will bubble up to the document from the button
  console.log("Bubble")
})

document.addEventListener("defaultEvent", () => {
  // This never gets called since the event cannot bubble up to the document from the button
  console.log("Default")
})

const button = document.querySelector("button")
button.dispatchEvent(bubbleEvent)
button.dispatchEvent(defaultEvent)

可取消 cancelable

cancelable 属性决定事件是否可以通过调用 e.preventDefault() 取消。默认是 false 不可以。如果该属性是 true 值,你可以调用 e.preventDefault() 方法。e.preventDefault() 会将事件 defaultPrevented 属性设置为 true。

const cancelableEvent = new Event("cancelableEvent", { cancelable: true })
const defaultEvent = new Event("defaultEvent", { cancelable: false })

document.addEventListener("cancelableEvent", e => {
  e.preventDefault()
  console.log(e.defaultPrevented) // True
})

document.addEventListener("defaultEvent", e => {
  e.preventDefault()
  console.log(e.defaultPrevented) // False
})

document.dispatchEvent(cancelableEvent)
document.dispatchEvent(defaultEvent)

组合 composed

composed 属性决定事件是否可以通过影子 dom 向上传播。默认值是 false。 该属性仅在你使用自定 HTML 元素和影子 DOM 的时候才适用,它所做的是允许事件在影子 DOM 外面传播。如果你想在影子 DOM 中触发的事件可以在影子 DOM 外被捕捉到,就将其设置为 true。

没听懂没关系,后面学着学着就懂了

给事件传递自定义数据

当你使用自定事件时,你希望自定义的数据传递给你的事件。使用 new Event 构造函数是不可能的,这也就是为什么会有第二种创建事件的方法。

const myEvent = new CustomEvent("myEvent", { detail: { hello: "World" } })

CustomEvent 构造函数取代 Event 构造函数。这与 new Event 的工作方式相同,但你可以将 detail 属性以及 bubbles,cancelable 和 composed属性一起传递给第二个参数。detail 属性中你设置的内容都会传递给事件监听器。

const myEvent = new CustomEvent("myEvent", { detail: { hello: "World" } })

document.addEventListener("myEvent", e => {
  console.log(e.detail) // { hello: "World" }
})

document.dispatchEvent(myEvent)

命名约定

在我们讲自定义双击事件的例子前,我想先讲讲命名约定。你可以为自定义事件命名任何你想要的名字,但是还是遵循命名约定,以更方便使用自己的代码。最普遍的命名约定事件,是为事件添加 custom: 前缀。

custom: 以区分自定义事件和本身的事件,而且,如果 JavaScript 添加与你的事件同名的新事件,它还可以确保你的代码不会中断。举个例子,如果 JavaScript 添加了一个名为 doubleclick 事件,然后你已经在时候 doubleclick 自定义事件了,那么你会遇到问题,因为你自定义代码将触发该事件,并且浏览器也会尝试触发它自己的副本。

// Always use some form of naming convention
const myEvent = new Event("custom:doubleClick")

双击事件

在这个例子中,我们将创建一个双击的事件,只要你在短时间内单击一个元素,就会触发该事件。该事件还会将按钮单击之间的总时间作为自定义数据传递。

首先,我们需要创建一个正常的单击事件监听器来确保是否有双击。

const button = document.querySelector("button")

const MAX_DOUBLE_CLICK_TIME = 500
let lastClick = 0
button.addEventListener("click", e => {
  const timeBetweenClicks = e.timeStamp - lastClick
  if (timeBetweenClicks > MAX_DOUBLE_CLICK_TIME) {
    lastClick = e.timeStamp
    return
  }

  // TODO: Double click happened. Trigger custom event.
  lastClick = 0
})

上面的代码使用 timeStamp 属性来确保按钮上单击事件之间的时间。如果点击之间的时间超过 500 毫秒。则会立刻返回并更新 lastClick 的值。一旦我们在 500 毫秒内点击了两次,我们将通过 if 检查并触发我们的双击事件。为此,我们需要创建我们的事件并调用它。

const button = document.querySelector("button")

const MAX_DOUBLE_CLICK_TIME = 500
let lastClick = 0
button.addEventListener("click", e => {
const timeBetweenClicks = e.timeStamp - lastClick
if (timeBetweenClicks > MAX_DOUBLE_CLICK_TIME) {
lastClick = e.timeStamp
return
}

// TODO: Double click happened. Trigger custom event.
lastClick = 0
})

对于我们自定义的事件,我们将所有选项都设置为 true,因为默认情况下,单击事件将所有这些属性设置为 true,而且我们希望双击的行为类似于正常的单击。我们也将 timeBetweenClicks 传递到 detail 选项中。最后,我们在事件的目标上调度事件,这里是按钮元素。我们剩下要做的最后一件事就是监听事件。

onst button = document.querySelector("button")

const MAX_DOUBLE_CLICK_TIME = 500
let lastClick = 0
button.addEventListener("click", e => {
const timeBetweenClicks = e.timeStamp - lastClick
if (timeBetweenClicks > MAX_DOUBLE_CLICK_TIME) {
lastClick = e.timeStamp
return
}

const doubleClickEvent = new CustomEvent("custom:doubleClick", {
bubbles: true,
cancelable: true,
composed: true,
detail: { timeBetweenClicks },
})
e.target.dispatchEvent(doubleClickEvent)
lastClick = 0
})

我们刚刚向按钮田间了一个简单的事件监听器,它将打印出 Double Click 之间的时间。

总结

自定义事件是 JavaScript 中处理手势和双击事件的好方案,最重要的是,他们非常容易实现和使用。

翻译来自:https://blog.webdevsimplified.com/2022-04/js-custom-events/

链接: https://fly63.com/article/detial/11423

js中addEventListener事件监听器参数详解

我们都知道addEventListener() 的参数约定是:useCapture是可选参数,默认值为false,目前DOM 规范做了修订:addEventListener() 的第三个参数可以是个对象值了。passive就是告诉浏览器我可不可以用stopPropagation...

js监听浏览器返回,pushState,popstate 事件,window.history对象

在WebApp或浏览器中,会有点击返回、后退、上一页等按钮实现自己的关闭页面、调整到指定页面、确认离开页面或执行一些其它操作的需求。可以使用 popstate 事件进行监听返回、后退、上一页操作。

CSS中的pointer-events属性实现点穿效果

具有层级关系的结构中,使用了pointer-events:none 属性将会使当前元素中的事件不会被捕获,从而实现了点穿的效果。而当代码示例中假如top元素具有子元素且显示指定pointer-events属性不为none的时候,top元素注册的事件将会被捕获/冒泡触发

js鼠标事件参数,获取鼠标在网页中的坐标

事件对象 event,JavaScript 将事件event作为参数传递,IE中把 event 事件对象作为全局对象 window 的一个属性,获取鼠标在网页中的坐标 = 鼠标在视窗中的坐标 + 浏览器滚动条坐标

js事件冒泡和默认事件处理(原生js、vue)

何为默认事件?比如 a 会跳转页面,submit 会提交表单等。普通js方法:e.preventDefault()函数。Vue.js方法: .prevent 是vue 的内置修饰符,调用了 event.preventDefault()阻止默认事件

js keyup、keypress和keydown事件 详解

js keyup、keypress和keydown事件都是有关于键盘的事件,当一个按键被pressed 或released在每一个现代浏览器中,都可能有三种客户端事件。

深入nodejs-核心模块Events详解(事件驱动)

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O的模型,使其轻量又高效。比如,文件操作中的fs事件流,网络编程所用到的tcp,http模块等,当你回想自己写的程序后,会发现很多操作都基于事件驱动,Events类。

纯CSS实现点击事件展现隐藏div菜单列表/元素切换

在写移动端导航的时候经常用到点击按钮出现/隐藏导航条的情况,最常见的方法当然还是前端框架直接调用,省心省力,不易出错;当然还有使用纯JS实现的小代码段。我这里整理了纯CSS实现方式,给需要的人和给自己做个笔记:实现原理利用CSS伪类:target

关于鼠标移动太快导致moseleave事件不触发的问题

我做的是一个table的编辑功能,当移入某行的时候展示编辑状态,在移出某行的时候显示的是原始状态,此时遇到一种情况,就是.当mousenter事件触发之后,由于鼠标移动得太快,同一个tr上绑定的mouseleave事件压根儿就没有执行。

Js事件传播流程

js事件传播流程主要分三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。在我们平常用的addEventListener方法中,一般只会用到两个参数,一个是需要绑定的事件,另一个是触发事件后要执行的函数

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!