在dom中发生事件与从dom中释放事件之间有什么区别?

时间:2019-04-20 17:57:12

标签: javascript asynchronous reactive-programming pure-function

我想了解当我单击dom元素时,然后在该元素上发生click事件并调用关联的事件处理函数。这是异步函数的基本示例。 我的问题与背后的实现有关。 当我们在用户屏幕上单击任何dom元素时,就会发生单击事件。元素上事件的发生与元素之间事件的发出之间有什么区别?发生和发射都一样吗?如果没有,那有什么区别?

当我们注册一个回调函数时,它们存储在内存中的什么位置?我不是在这里询问事件循环(主堆栈和回调队列)。

如何创建事件对象以及谁创建它们? 事件如何映射到关联的回调函数?

1 个答案:

答案 0 :(得分:0)

哇,一次有很多问题。呵呵,元帅们不会喜欢的!但这还需要冗长而详细的答案。

  

元素上的事件发生与元素之间的事件发射之间有什么区别?

这种差异不是常规的[尚]。因此,这主要来自于我自己的观察,我认为很少有人会反对我。

  

发生和发射都一样吗?

不,它们是不同的。

  

如果没有,那有什么区别?

发生的事实是用户实际上做了一些事情:单击,滚动,拖动开始,拖动结束,悬停,右键单击等...

发射是与事件关联的逻辑。实际上,您可以运行事件发射,而无需等待特定事件的发生。

示例:

以下代码将侦听器附加到click事件。

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运行时崩溃时,它们全部消失。

  

事件如何映射到关联的回调函数?

这取决于实现。如果您真的决心要实现它,可以检查this Event API implementation:它是TypeScript,但您会发现很难。 (我承认代码中有很多注释)。但是当我在那里使用WeakMap时,其他实现依赖于对象映射+数组或事件Set。

  

如果没有,那有什么区别?

一个事件与一个手工事件之间的内部差异在于isTrusted(布尔)属性,当该事件由用户操作/输入和{{ 1}}否则。是documented here