深入了解Mindmaps的浏览器事件
#javascript #browser #dom #events

这是对DOM事件的复杂性的广泛探索。首先,我们将深入研究各种类型的DOM事件,研究它们的每个独特特征及其触发方式。此外,我们将仔细研究一些更常见的DOM事件方面,例如事件的传播和冒泡。

什么是浏览器活动?

让我们简单地以这种方式说一个事件是一个对象,其中包含有关该特定事件的信息的属性,例如,触发了该事件的元素以及有关该特定事件的许多其他信息。

DOM event mindmap

事件可以概括为2个类别

  • 用户代理事件
  • 合成事件

根据用户交互或任何其他浏览器(页面)任务完成浏览器的用户代理事件已完成。

例如

  1. 用户点击按钮
  2. 用户提交表格
  3. 所有资源已下载。

,并且可能会更多,我们可以在事件中添加听众以收听事件

window.addEventlistner('load',(event)=>{console.log(event));

合成事件

Synthetic events

另一方面,合成事件是应用程序创建/发射的事件。

例如

const event = new Event('myEvent', {bubbles:true, cancelable: true});

//dispatch events
document.dispatchEvent(event);

//events can be dispatched from any element
document.getElementbyId('myDiv').dispatchEvent(event)

如果我们想传递数据,则可以使用CustomEvent()

const event = new CustomEvent('myCustomEvent', {detail: {message:'hello world'});

elem.addEventListner('myCustomEven', (event)=>{
console.log(event.detial.message)
})

isTrusted是事件对象中的属性,用于用户代理派遣事件,而对启动的应用程序(开发人员)false。

事件阶段

Event Phase

当我们进一步检查事件对象时,我们还会获得属性名称eventPhase。为了了解此属性,让我们首先了解什么是CAPTURING_PHASEBUBBLEING_PHASE

当事件派遣时,将在事件中发生在文档(root),然后返回目标元素(在上图按钮中)。从上到下的流量称为捕获相位,底部到顶部称为***** 起泡阶段。 *** **让我们向前迈出一步,并用代码理解上图

<!DOCTYPE html>
<html>

<head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
</head>

<body >
    <form id='submit_form' style="border:1px solid red; padding: 4rem">
    <button type='submit' id='submit_button'>Submit<button>
    </div>
    </form>

    <script>

            function eventListener(event) {
                        console.log({
                        target: event.target,
                        currentTarget: event.currentTarget,
                        phase: event.eventPhase,
                        type: event.type
                  });
            }

        const form = document.getElementById("submit_form");
        const buttonContainer = document.getElementById("button-wrapper");
        const submit = document.getElementById("submit_button");

        form.addEventListener("click", eventListener);
        buttonContainer.addEventListener("click", eventListener);
        submit.addEventListener("click", eventListener);

    </script>
</body>

</html>

这是一个漫长的例子,让我们将其分解。我们有一个简单的表格,后来我们将一些事件听众附加到它上。 addEventListner()函数获取3个参数

  • 事件侦听器应该听的事件名称
  • 应该称呼的回调函数。
  • 最后一个是选项 usecapture。这是一个可选的参数。

所有参数都以我们关心的唯一论点为 option usecapture。

该选项具有这些参数。

  • 捕获:默认值为false。该事件将首先用附加事件侦听器的当前元素(即在DOM树中的元素)捕获,然后将其派发到任何事件目标
  • 一次:应调用事件一次,默认情况下删除
  • 被动:如果TUME告诉浏览器,即使在回调函数中存在preventDefault,回调函数也不会具有preventDefault().
  • 信号:它用于通过提供AbortSignal来删除事件听众。我们将稍后在此博客中讨论中止信号。

捕获和冒泡阶段

在上面的示例中,我们在文档,正文,表单和按钮上附上了上述示例,输出将如下

{target: button#submit_button, currentTarget: button#submit_button, phase: 2, type: 'click'}
{target: button#submit_button, currentTarget: div#button-wrapper, phase: 3, type: 'click'}
{target: button#submit_button, currentTarget: form#submit_form, phase: 3, type: 'click'}

要理解这一点,我们首先需要研究Event对象。用户代理生成的事件对象主要具有这些属性

Event Object

  • type:类型是单击,提交等事件的类型。您可以阅读有关它的更多信息。
  • eventTaget:返回事件发生的元素或null。
  • currentTarget:返回正在收听事件的元素
  • eventPhase:这是有趣的。事件阶段通常返回这些值之一0,1,2,3。这些价值是什么?事件阶段有这些枚举
NONE = 0
CAPTURING_PHASE = 1;
AT_TARGET = 2;
BUBBELING_PHASE = 3;

让我们一一理解这些值中的每一个。在上面的示例上下文中,<button />元素由div包裹,该元素进一步嵌套在form中。因此,单击按钮后,divfrom处于捕获阶段。但是在控制台中,我们没有看到任何eventPhase是1(即捕获)事件听众没有被调用。

要在捕获阶段中调用事件侦听器回调函数,我们需要在事件中指定true

 document.body.addEventListener("click", eventListener, true);

// or
 document.body.addEventListener("click", eventListener, { capture:true });

传播

现在我们对事件阶段有了深刻的了解。让我们进一步研究如何阻止处理程序被调用。我们有2种停止事件传播的方法。

  • event.stopPropagation()
  • event.stopImmediatePropagation()

假设我们在元素上附上了多个事件处理程序。我们有stopHandler()eventListenerLogs()



<!DOCTYPE html>
<html>
   <head>
      <title>Parcel Sandbox</title>
      <meta charset="UTF-8" />
   </head>
   <body>
      <form id='submit_form' style="border:1px solid red; padding: 4rem">
         <div id='button-wrapper' style="border:1px solid black; padding: 4rem"">
            <button type='button' id='submit_button'>Submit<button>
         </div>
      </form>
      <script>
         function stopHandler(event) {
           event.stopPropagation();
           console.log({
             target: event.target,
             element: event.currentTarget,
             phase: event.eventPhase,
             type: event.type
           });
         }

         const form = document.getElementById("submit_form");

                    document.body.addEventListener("click", eventListener, false);
         form.addEventListener("click", stopHandler, false);
         form.addEventListener("click", eventListener, false);

      </script>  
   </body>
</html>

我们已将事件处理程序附加到bodyform元素。当我们单击按钮时,事件发生在BUBBLEING_PHASE中,事件传播的顺序应为

Propogation
但是,由于我们有event.stopPropagation(),因此在形式级别上。控制台O/P是

{target: button#submit_button, element: form#submit_form, phase: 3, type: 'click'}

{target: button#submit_button, element: form#submit_form, phase: 3, type: 'click'}

我们必须将事件处理程序附加到form元素上。

如果我们只想只听一次事件,那么我们可以使用event.stopImmediatePropagation()

function stopHandler(event) {
           event.stopImmediatePropagation();
           console.log({
             target: event.target,
             element: event.currentTarget,
             phase: event.eventPhase,
             type: event.type
           });
         }

现在输出为

{target: button#submit_button, element: form#submit_form, phase: 3, type: 'click'}

可取消

根据事件的初始化方式,可取消的事件仅阅读属性返回truefalse。使用event.preventDefault()可以取消大多数本机事件。称此功能就像事件从未发生过。我们可以创建一个syntheticEvent并使其不可能。

const myCoustomEvent = new CoustomEvent("my-coustom",{
cancelable:true
})

document.addEventListener('my-event', function (event) {
   event.preventDefault()
})

console.log(
  document.dispatchEvent(event) ? 'Event was not cancelled' : 'Event was cancelled'
)

//output
//"Event was cancelled"

如果我们将cancelable属性更改为false,则输出将为Event was not cancelled

预防默认

event.preventDefault()将阻止本地元素动作发生。这意味着该事件的工作方式不会像事件从未发生过一样起作用。

结论。

总结了我们关于事件以及如何创建自定义事件的讨论。我们介绍了触发事件的各个阶段并探讨了可取消事件。

感谢您的阅读。如果我错过了任何东西,请在评论部分告诉我。