前言:

相信大家肯定处理过很多的事件监听,比如点击事件或者表单提交。事件监听对许多用例来说很有帮助,但是有时我们需要创建自己的自定义事件来处理复杂的交互。

怎么创建自定义事件

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

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 中处理手势和双击事件的好方案,最重要的是,他们非常容易实现和使用。

到此这篇关于如何创建 JavaScript 自定义事件的文章就介绍到这了,更多相关JavaScript 自定义事件内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

如何创建 JavaScript 自定义事件的更多相关文章

  1. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  2. HTML5数字输入仅接受整数的实现代码

    这篇文章主要介绍了HTML5数字输入仅接受整数的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. amaze ui 的使用详细教程

    这篇文章主要介绍了amaze ui 的使用详细教程,本文通过多种方法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. html5简介_动力节点Java学院整理

    这篇文章主要介绍了html5简介,用于指定构建网页的元素,这些元素中的大多数都用于描述网页内容,有兴趣的可以了解一下

  5. ios 8 Homescreen webapp,关闭和打开iPad停止javascript

    我有一个适用于iPad的全屏HTML5网络应用程序,并且刚刚安装了IOS8来试用它,它一切正常,直到你关闭并重新启动iPad.一旦web应用程序重新启动javascript就会停止并加载新页面不会重新启动它.在iPad上的Safari中打开同一页面时,关闭和打开iPad会继续按预期工作.其他人注意到了这个或想出了一个解决方案吗?解决方法这似乎是我在iOS8.1.1更新中解决的.

  6. iOS 6 javascript与object.defineProperty的间歇性问题

    当访问使用较新的Object.defineProperty语法定义属性的对象的属性时,有没有其他人注意到新iOS6javascript引擎中的间歇性错误/问题?https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty我正在看到javascript失败的情况,说

  7. ios – 如何使用JSExport导出内部类的方法

    解决方法似乎没有办法将内部类函数导出到javascript.我将内部类移出并创建了独立的类,它起作用了.

  8. 静音iOS推送通知与React Native应用程序在后台

    我有一个ReactNative应用程序,我试图获得一个发送到JavaScript处理程序的静默iOS推送通知.我看到的行为是AppDelegate中的didReceiveRemoteNotification函数被调用,但是我的JavaScript中的处理程序不会被调用,除非应用程序在前台,或者最近才被关闭.我很困惑的事情显然是应用程序正在被唤醒,并且它的didReceiveRemoteNotifi

  9. ios – 内存泄漏与UIWebView和Javascript

    清楚地包含一个Javascript文件到我的HTML是使UIWebView泄漏内存.当我重复使用相同的UIWebView对象时,或者每当我有内容实例化一个新的漏洞时,会出现泄漏的事实,导致我认为必须有一些JavaScript文件被loadHTMLString处理,导致泄漏.有人知道如何解决这个问题吗?

  10. iOS应用程序的UI自动化测试如何与乐器和Javascript

    从WWDC2010视频会议中了解iOS应用程序的自动化UI测试,但没有实践.从代码项目project,我们可以有一个例子.这个问题在这里听到有涉及这个的人.任何限制?解决方法我建议从AlexWollmer开始使用thisblogpost.他创建了一个非常有用的JavaScript库:tuneup_jswithtest()函数,它允许测试分离和有用的帮助者以及为自动化仪器编写测试的断言.

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部