我想了解当我单击一个 dom 元素时,该元素上会发生单击事件并调用相关的事件处理函数。这是一个异步函数的基本示例。我的问题与这背后的实现有关。当我们单击用户屏幕上的任何 dom 元素时,会发生单击事件。在元素上发生事件和逐个元素发出事件之间有什么区别?发生和发射是一样的吗?如果不是,那有什么区别?
另外当我们注册一个回调函数时,它们在内存中存储在哪里?我不是在这里询问事件循环(主堆栈和回调队列)。
事件对象是如何创建的以及是谁创建的?事件如何映射到关联的回调函数?
我想了解当我单击一个 dom 元素时,该元素上会发生单击事件并调用相关的事件处理函数。这是一个异步函数的基本示例。我的问题与这背后的实现有关。当我们单击用户屏幕上的任何 dom 元素时,会发生单击事件。在元素上发生事件和逐个元素发出事件之间有什么区别?发生和发射是一样的吗?如果不是,那有什么区别?
另外当我们注册一个回调函数时,它们在内存中存储在哪里?我不是在这里询问事件循环(主堆栈和回调队列)。
事件对象是如何创建的以及是谁创建的?事件如何映射到关联的回调函数?
哇,一下子问了很多问题。呵呵,元帅们不会喜欢吧!但这也需要一个长而详细的答案。
在元素上发生事件和逐个元素发出事件之间有什么区别?
这种差异不是传统的[还]。所以这主要来自我自己的观察,我想很少有人会不同意我的观点。
发生和发射是一样的吗?
不,它们是不同的。
如果不是,那有什么区别?
发生的事情是用户实际上做了一些事情:单击、滚动、拖动开始、拖动结束、悬停、右键单击等......
发射是与发生相关的逻辑。实际上,您可以运行事件发射而无需等待特定的发生。
例子 :
以下代码将侦听器附加到单击事件。
const actionable = document.querySelector( 'button[type="button"]' );
actionable.addEventListener( 'click', () =>
{
alert( 'Clicked me' );
});
<button type="button" class="click-me">
Click me
</button>
每当发出click
事件时,都会执行回调。请注意,我说过,当事件将被发出时。(不是用户点击它的时候。)click
现在,Web 浏览器确保当用户单击时click
触发该事件,并且 DOM API 确保执行我们的回调。这是启动它的用户的情况。
但是,我们仍然可以在没有用户实际点击的情况下模仿这种行为。
const actionable = document.querySelector( 'button[type="button"]' );
const actionableState = document.querySelector( 'button[type="button"] > span' );
const hoverable = document.querySelector( 'div.hover-me' );
const hoverableState = document.querySelector( 'div.hover-me > span' );
let count = 0;
actionable.addEventListener( 'click', () =>
{
actionableState.innerText = ++count;
});
hoverable.addEventListener( 'mouseenter', () =>
{
hoverableState.innerText = 'Hovered';
const event = new Event( 'click' );
actionable.dispatchEvent( event );
});
hoverable.addEventListener( 'mouseout', () =>
{
hoverableState.innerText = '-';
});
.click-me > span {
font-style: italic;
}
.click-me > span:before { content: '[ '; }
.click-me > span:after { content: ' time(s) ]'; }
.hover-me {
padding: 3em;
margin: 1em 0;
text-align: center;
border-radius: 3px;
background-color: red;
display: inline-block;
}
<button type="button" class="click-me">
Click me <span>0</span>
</button>
<div class="hover-me">
Hover me, please
<br/>
<span>-</span>
</div>
当用户将鼠标悬停在盒子上时,我们模拟了click
事件。我们创建了一个人工点击事件并发出它(dispatchEvent()
)。这基本上是事件发射。
它们存储在内存中的什么位置?
是的,在内存中。当页面死掉(或关闭)或 JS 运行时崩溃时,它们都会消失。
事件如何映射到关联的回调函数?
这取决于实现。如果您真的致力于了解它是如何实现的,您可以查看这个 Event API 实现:它是 TypeScript,但您不会觉得很难。(我承认代码有很多注释)。但是当我在那里使用 WeakMap 时,其他实现依赖于对象映射 + 数组或事件集。
如果不是,那有什么区别?
发生的事件和手工制作的事件之间的内部差异在于isTrusted
(布尔)属性,即true
当事件由用户操作/输入或false
其他情况触发时。它记录在这里。