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

浏览器只是区分了不同事件的接口,不同接口有不同的属性而已。即根据不同接口创建出的对象,具有不同的事件属性。
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,所以都具有以下属性。我们来一一介绍一下

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) // 触发事件

// 单纯设置事件不能冒泡
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) // 触发事件

可以阻止事件的继续传播(冒泡或者捕获),可以使用cancelBubble = truestopPropagation()代替。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表示事件流当前处于哪一个阶段。表示该事件的默认操作是否已被阻止。默认情况下,它被设置为returnValuetrue,即允许进行默认操作。将该属性设置为false即可阻止默认操作。 可以使用preventDefault()代替。他是srcElementtarget的别名。target事件分派到的对象的引用。timeStamp返回事件创建的时间(以毫秒为单位)。type表示该事件对象的事件类型。即定义的事件名称。composedPath()返回事件触发的流程节点对象。如果自定义元素是闭合的那么该流程将包含自定义元素内部元素。如果事件在创建时指定composed: false,那么事件流程将不会包含自定义元素外部dom对象。
- ~~
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)

往期年度总结
往期文章
专栏文章
🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论, 支持一下博主~
公众号:全栈追逐者,不定期的更新内容,关注不错过哦!
转载自:https://juejin.cn/post/7418394742532243456