如何理解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 = 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对象。- ~~
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