likes
comments
collection
share

如何理解js的DOM事件系统js事件的继承关系 浏览器只是区分了不同事件的接口,不同接口有不同的属性而已。 EventT

作者站长头像
站长
· 阅读数 19

js事件的继承关系

如何理解js的DOM事件系统js事件的继承关系 浏览器只是区分了不同事件的接口,不同接口有不同的属性而已。 EventT

浏览器只是区分了不同事件的接口,不同接口有不同的属性而已。即根据不同接口创建出的对象,具有不同的事件属性。

EventTarget

创建一个新的 EventTarget对象实例。即创建一个事件对象,用来监听和派发事件,作用等同于DOM, document, window派发和监听事件。

DOM.dispatchEvent

指定的事件目标派发一个 Event,并以合适的顺序(同步地)调用所有受影响的 EventListener。即利用程序去触发指定DOM的对应事件。

<div id="div">dispatchEvent触发click事件</div>
<script>
    const div = document.getElementById("div")
    div.addEventListener("click", () => {
      console.log("click")
    })
    // 类似于手动点击
    div.dispatchEvent(new Event("click"))
</script>
  • 相关对象

使用dispatchEvent需要具有两个对象,一个是要有派发对象(DOM, document, window等等),另一个是派发的事件对象(即通过Event及其子类创建的对象)。

需要注意的是,我们在通过dispatchEvent派发事件时,该对象的事件监听器需要提前注册好,因为是同步派发。而不像浏览器提供的一些异步任务api。

<script>
    const div = document.getElementById("div")
    div.dispatchEvent(new Event("click"))
    // 不会被监听到
    div.addEventListener("click", () => {
      console.log("click")
    })
</script>
  • 返回值

派发的事件是否有取消(new Event("click", {cancelable: true})),并且是监听器(多个之一)处理逻辑是否调用了event.preventDefault()。如果二者之一不满足,那么将返回true,否则返回false

 div.addEventListener("click", (event) => {
      console.log("click" ,event, event.target)
      // event.preventDefault()
    })
    const res = div.dispatchEvent(new Event("click", {cancelable: true})) // true
div.addEventListener("click", (event) => {
      console.log("click" ,event, event.target)
      // event.preventDefault()
    })
    div.addEventListener("click", (event) => {
      console.log("click2" ,event, event.target)
      event.preventDefault()
    })
    div.dispatchEvent(new Event("click", {cancelable: true})) // false

Event

它是所有事件的主接口。并且也通过了构造函数,可以让我们创建任意名称的事件。并且可以在创建事件对象时可以传入一些事件配置。自定义的事件默认都不能冒泡。

  • "bubbles",默认值为 false,表示该事件是否冒泡。
  • "cancelable",默认值为 false,表示该事件能否被取消。
  • "composed",可选,默认值为 false,指示事件是否会在影子 DOM 根节点之外触发侦听器。是否可以冒泡到自定义元素之外。
const div = document.getElementById("div")
document.body.addEventListener("click", (event) => {
  console.log("body click", event, event.target) // 不会触发,由于自定义事件bubbles: false
})
div.addEventListener("click", (event) => {
  console.log("click" ,event, event.target)
  event.preventDefault()
})
div.addEventListener("click", (event) => {
  console.log("click2" ,event, event.target)
})
div.dispatchEvent(new Event("click", {cancelable: false, bubbles: false}))

Event事件对象属性

不同的事件类型事件对象具有不同的属性,所有事件都继承自Event,所以都具有以下属性。我们来一一介绍一下

如何理解js的DOM事件系统js事件的继承关系 浏览器只是区分了不同事件的接口,不同接口有不同的属性而已。 EventT

  • isTrusted 表示事件是否由用户行为触发,例如代码触发(dom.click, dom.dispatch...)都返回false。
  • bubbles 表明事件是否会沿 DOM 树向上冒泡。创建事件的时候可以指定事件是否可以冒泡new Event("click", {bubbles: false})注意这个只是规定事件不能进行冒泡,但是如果事件监听器设置在捕获阶段进行触发,事件依旧会被触发。
    document.body.addEventListener("click", (event) => {
      console.log("body click", event, event.target, event.currentTarget) // event.currentTarget只能在事件处理器中使用,在控制台直接看event是null
    }, true)
    div.addEventListener("click", (event) => {
      console.log("click" ,event, event.target)
    }, true)
    div.addEventListener("click", (event) => {
      console.log("click2" ,event, event.target)
    }, true)
    const event = new Event("click", {cancelable: false, bubbles: false}) // 设置不能进行冒泡
    div.dispatchEvent(event) // 触发事件

如何理解js的DOM事件系统js事件的继承关系 浏览器只是区分了不同事件的接口,不同接口有不同的属性而已。 EventT

// 单纯设置事件不能冒泡
    document.body.addEventListener("click", (event) => {
      console.log("body click", event, event.target, event.currentTarget) // event.currentTarget只能在事件处理器中使用,在控制台直接看event是null
    }, false)
    div.addEventListener("click", (event) => {
      console.log("click" ,event, event.target)
    }, false)
    div.addEventListener("click", (event) => {
      console.log("click2" ,event, event.target)
    }, false)
    const event = new Event("click", {cancelable: false, bubbles: false}) // 设置不能进行冒泡
    div.dispatchEvent(event) // 触发事件

如何理解js的DOM事件系统js事件的继承关系 浏览器只是区分了不同事件的接口,不同接口有不同的属性而已。 EventT

  • cancelBubble = true 可以阻止事件的继续传播(冒泡或者捕获),可以使用stopPropagation()代替。
  • cancelable 事件是否可以被取消。即通过preventDefault()取消。创建事件的时候可以指定事件是否可以被取消new Event("click", {cancelable: false})
  • composed 指示该事件是否可以从 Shadow DOM 传递到一般的 DOM。
  • currentTarget 标识事件处理器所附加的元素。即绑定事件监听器的对象(一般在事件委托的时候有用)。currentTarget 的值仅在事件处理器中可用。在事件处理器外部,它将为 null
  • defaultPrevented 当前事件是否调用了 event.preventDefault()方法。如果事件是可以取消的(new Event("click", {cancelable: true})),并且在任意的事件监听器中调用了preventDefault(),该值都会变成true,否则为false
  • eventPhase 表示事件流当前处于哪一个阶段。
  • returnValue 表示该事件的默认操作是否已被阻止。默认情况下,它被设置为 true,即允许进行默认操作。将该属性设置为 false 即可阻止默认操作。 可以使用preventDefault()代替。
  • srcElement 他是target的别名。
  • target 事件分派到的对象的引用。
  • timeStamp 返回事件创建的时间(以毫秒为单位)。
  • type 表示该事件对象的事件类型。即定义的事件名称。
  • composedPath() 返回事件触发的流程节点对象。如果自定义元素是闭合的那么该流程将包含自定义元素内部元素。如果事件在创建时指定composed: false,那么事件流程将不会包含自定义元素外部dom对象。 如何理解js的DOM事件系统js事件的继承关系 浏览器只是区分了不同事件的接口,不同接口有不同的属性而已。 EventT
  • ~~initEvent() ~~用来初始化由Document.createEvent() 创建的 event 实例。
  • preventDefault() 阻止事件的默认行为。 如果事件不能取消,他是没有效果的。虽然阻止默认行为,但是冒泡和捕获是不会阻止的。
  • stopPropagation() 阻止捕获和冒泡阶段中当前事件的进一步传播。
  • stopImmediatePropagation() 阻止监听同一事件的其他事件监听器被调用。即在同一个事件触发对象中阻止事件监听器被调用。并且也可以阻止冒泡或者捕获到其他事件触发对象中。

日常开发中的使用

例如抖音搜索,输入文本后,我们必须按下回车Enter键才会进行搜索。所以我们就需要通过KeyboardEvent来创建一个事件帮助我们进行搜索。

const input = document.querySelector(".semi-input.semi-input-default")
// 定义一个鼠标按下enter事件
const keyEvent =  new KeyboardEvent("keydown", {
  bubbles: true,
  cancelable: false,
  ctrlKey: false,
  metaKey: false,
  altKey: false,
  which: 13,
  keyCode: 13,
  key: "Enter",
  code: "Enter",
});
input.dispatchEvent(keyEvent)

如何理解js的DOM事件系统js事件的继承关系 浏览器只是区分了不同事件的接口,不同接口有不同的属性而已。 EventT

往期年度总结

往期文章

专栏文章

🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏✍️评论,    支持一下博主~

公众号:全栈追逐者,不定期的更新内容,关注不错过哦!

转载自:https://juejin.cn/post/7418394742532243456
评论
请登录