Heim  >  Artikel  >  Web-Frontend  >  Ereignis-Bubbling und Zeiterfassung von JavaScript-Ereignissen (Zusammenfassungsfreigabe)

Ereignis-Bubbling und Zeiterfassung von JavaScript-Ereignissen (Zusammenfassungsfreigabe)

WBOY
WBOYnach vorne
2021-12-23 18:49:382328Durchsuche

Dieser Artikel bietet Ihnen eine detaillierte Erläuterung der Grundkenntnisse über Ereignisse in JavaScript, einschließlich Ereignis-Bubbling und Zeiterfassung. Ich hoffe, er wird Ihnen hilfreich sein.

Ereignis-Bubbling und Zeiterfassung von JavaScript-Ereignissen (Zusammenfassungsfreigabe)

1. Ereignissprudeln und Ereigniserfassung

Wenn wir auf ein Element auf der Webseite klicken, beispielsweise auf ein p-Element. Wenn Sie sorgfältig darüber nachdenken, haben wir nicht nur auf dieses p-Element geklickt, sondern auch auf konzentrische Kreiselemente mit p als Mittelpunkt, z. B. das übergeordnete Element des Elements, den äußeren Körper, das übergeordnete HTML-Element des Körpers usw äußeres Elementschichtdokument. Die Weitergabe von Ereignissen zwischen diesen verschachtelten Elementen wird als Ereignisfluss bezeichnet.

  • 1. Ereignis-Bubbling
  • 1. Der Ereignisfluss von IE beginnt beim spezifischsten Element und breitet sich Schritt für Schritt aus. Der Event-Handler, den wir mit DOM0 hinzugefügt haben, wird während der Event-Bubbling-Phase verarbeitet. Zum Beispiel:
<html>
  <head>
    <script type="text/javascript">

      window.onload = bubblingHandle;      function bubblingHandle() {
          //内层p处理程序
          document.getElementById("inner").onmousedown     = function() {
              alert("inner p");
          }          //外层p处理程序
          document.getElementById("outer").onmousedown = function() {
              alert("outerp");
          }

          document.onmousedown = function() {
              alert("document");
          }
      } 
      -->    </script>
  </head>
  <body>
    <p id="outer" style="background-color:black; padding: 15px;">
        <p id="inner" style="background-color:white; padding: 5px;"></p>
    </p>
  </body></html>

Wenn Sie auf das weiße p in der inneren Ebene klicken, wird es nacheinander angezeigt:

inner p
outer p
document

Ereigniserfassung

Der von Netscape vorgeschlagene Ereignisfluss wird als Ereigniserfassung bezeichnet, was fast das Gegenteil von ist IE. Ereignisse werden zuerst vom am wenigsten spezifischen Element empfangen und dann an bestimmte Knoten weitergeleitet.


2. Ereignisverarbeitung auf DOM0-Ebene

Ereignisse werden durch bestimmte Verhaltensweisen ausgelöst, die auf der WEB-Seite auftreten. Wenn Sie beispielsweise die linke Maustaste auf einem bestimmten Seitenelement drücken, eine bestimmte Taste auf der Tastatur drücken oder ein Objekt den Fokus erhält oder verliert, wird das entsprechende Ereignis ausgelöst. Die Interaktion zwischen JavaScript und HTML wird durch Ereignisse erreicht. Wir verwenden Ereignis-Listener, um Ereignisse zu „registrieren“, und der entsprechende Code wird ausgeführt, wenn das Ereignis auftritt.

Der Ereignishandler der DOM-Ebene 0 wird aufgrund seiner Einfachheit und browserübergreifenden Unterstützung weiterhin von allen Browsern unterstützt.

Event-Handler über DOM0-Level-Methode angeben

dies im Event-Handler
  • Event-Handler über DOM0-Level-Methode löschen
  • Event-Handler über DOM0-Level-Methode angeben
  • Event-Handler über DOM0-Level-Methode angeben Die Methode ist sehr einfach. Rufen Sie zunächst eine Referenz auf das zu bedienende Element ab und weisen Sie dann dem entsprechenden Ereignishandlerattribut des Elements eine Funktion zu. (Jedes Element, einschließlich Fenster und Dokument, verfügt über ein eigenes Ereignishandlerattribut.) Beachten Sie, dass auf diese Weise hinzugefügte Ereignishandler während der Bubbling-Phase des Ereignisflusses verarbeitet werden.

Bezüglich der Event-Handler-Attribute gibt es folgende Punkte, die erklärt werden müssen:

1. Die Event-Handler-Attribute sind alle in Kleinbuchstaben geschrieben, beginnend mit „on“, gefolgt vom Event-Typ: 事件处理程序属性。(每个元素包括window和document都拥有自己的事件处理程序属性。)注意,这种方法添加的事件处理程序将在事件流的冒泡阶段被处理。

有关事件处理程序属性,有以下几点需要说明:

1、事件处理程序属性全部小写,以”on”开头,后面跟事件类型:

onclick  //单击鼠标
onload  //图像或页面载入完成
onmouseover  //将鼠标移动到某元素上面
onmousemove  //移动鼠标
onfocus  //对象获得焦点

2、每个元素如img、a、input、form包括window和document都拥有自己的事件处理程序属性。如:

document.getElementById("btn1").onclick  //btn1上单击鼠标
document.getElementById("img1").onmouseover  //鼠标移动到img1
document.getElementById("img1").onmerror  //img1图像无法载入

接下来,给事件处理程序属性赋值即可完成事件处理程序方法的指定。例如,当鼠标移动到”img1”上时,弹出对话框”This is a nice pic!”:

var pic1 = document.getElementById("img1");
pic1.onmouseover = function() {
    alert("This is a nice pic!");
};

特别注意:如果以上代码处于文档的底部,在页面刚刚加载时,我们将鼠标移动到img1上面。有可能由于代码尚未执行,不会弹出我们设定的对话框!如今,这个延迟已经十分短暂。

事件处理程序中的this

通过DOM0级方法指定的事件处理程序,属于元素方法

6c62a7e2513a7465a5a873220f3f5dac
...//省略
8019067d09615e43c7904885b5246f0a
  89e3bb261a36e34e3f1c9a90f67afd83
2cacc6d41bbb37262a98f745aa00fbf0
2 wie img, a, Input, form, einschließlich window und document, haben alle ihre eigenen Event-Handler-Attribute. Beispiel:

pic1.onmouseover = null;

Als nächstes weisen Sie dem Event-Handler-Attribut einen Wert zu, um die Spezifikation der Event-Handler-Methode abzuschließen. Wenn sich die Maus beispielsweise auf „img1“ bewegt, erscheint das Dialogfeld „Das ist ein schönes Bild!“:

addEventListener()  //指定事件处理程序
removeEventListener()  //删除事件处理程序
Besonderer Hinweis: Wenn sich der obige Code am Ende des Dokuments befindet, wenn die Seite gerade geladen wurde , bewegen wir die Maus zu img1 oben. Es ist möglich, dass das von uns festgelegte Dialogfeld nicht angezeigt wird, da der Code noch nicht ausgeführt wurde! Heute ist diese Verzögerung sehr kurz.

this in the event handler

Der über die DOM0-Level-Methode angegebene Event-Handler gehört zur Element-Methode. Daher bezieht sich unser this im Event-Handler auf dieses Element! Lassen Sie uns das anhand des folgenden Beispiels veranschaulichen:

6c62a7e2513a7465a5a873220f3f5dac
...
8019067d09615e43c7904885b5246f0a
  0e82aacda029e768165406ce66a9f59e
2cacc6d41bbb37262a98f745aa00fbf0

Ereignishandler über Methode auf DOM0-Ebene löschen

    Um den Ereignishandler zu löschen, setzen Sie einfach das entsprechende Ereignishandlerattribut auf null:
  • handle1!
    handle2!
  • 3. addEventListener und removeEventListener
  • Derzeit unterstützen fast alle Browser das DOM0-Ereignismodell, Entwickler werden jedoch ermutigt, das neue DOM2-Modell zu verwenden. Es gibt zwei wesentliche Unterschiede zwischen dem DOM2-Modell und DOM0:

1. DOM2 ist nicht auf Event-Handler-Attribute angewiesen

2 Mehrere Handler können gleichzeitig für dasselbe Ereignis eines Objekts registriert und ausgeführt werden Der Reihe nach in der Reihenfolge der Registrierung.

DOM2 definiert 2 Methoden:

btn1.removeEventListener("click", handle2, false);

Die Verwendung dieser beiden Methoden ist wie folgt. Der erste ist der Name des zu verarbeitenden Ereignisses (außer on). ), die 2. Event-Handler-Funktion, die 3. boolesche Variable:

Zum Beispiel fügen wir 2 Event-Handler für das Klickereignis der Schaltfläche btn1 hinzu, und die Event-Handler werden in der Event-Bubbling-Phase verarbeitet:

 btn1.addEventListener("click", function(){
     alert("click!");
 }, false);

 btn1.removeEventListener("click", function(){
     alert("click!");
 }, false);  //无法取消!

Wenn auf btn1 geklickt wird Nacheinander wird ein Dialogfeld angezeigt:

attachEvent()
detachEvent()
🎜 Wir können die Methode „removeEventListener()“ verwenden, um den gerade angegebenen Ereignishandler zu löschen. Beachten Sie, dass die Parameter konsistent sein müssen: 🎜
6c62a7e2513a7465a5a873220f3f5dac
...
8019067d09615e43c7904885b5246f0a
  84f07fc1f7167f067b3f15a898dda831
2cacc6d41bbb37262a98f745aa00fbf0
🎜 Klicken Sie zu diesem Zeitpunkt auf die Schaltfläche btn1. Es wird nur handle1 angezeigt! 🎜🎜Es ist wichtig zu beachten, dass wir, wenn wir eine anonyme Funktion zur Angabe des Event-Handlers verwenden, die Methode „removeEventListener()“ nicht verwenden können, um den Event-Handler zu entfernen: 🎜
 btn1.addEventListener("click", function(){
     alert("click!");
 }, false);

 btn1.removeEventListener("click", function(){
     alert("click!");
 }, false);  //无法取消!

这样是无法取消以上指定的事件处理程序的!因为上面addEventListener和removeEventListener中的2个事件处理函数虽然代码相同,实质上是2个不同的函数引用。

另外,强调一点,以上两个函数的第一个参数(要处理的事件名)是没有on前缀的。这一点和IE不同,后面会说明。

tips: IE9, Firefox, Safari, Chrome以及Opera均支持DOM2级事件处理程序。

DOM2事件处理程序中的this

DOM2事件处理程序和DOM0相同,它们的this都在其依附的元素作用域中运行。this的指代参考DOM0的示例。这里之所以要特别指出DOM2的this,是为了和IE事件处理程序进行区分。IE中事件处理程序this与事件指定方式有关。

四、IE事件处理程序及跨浏览器支持

attachEvent()与detachEvent()

IE并没有提供对W3C事件模型的支持,其实现了2个和DOM2模型类似的方法:

attachEvent()
detachEvent()

这两个方法只接收2个参数:事件名称以及事件处理函数。由于IE8及更早版本只支持事件冒泡,这两个方法添加的事件处理程序会在事件冒泡阶段被执行。

和DOM2不同的是:

  • 1、IE事件处理方法运行作用域为全局作用域,this指代window;
  • 2、第一个参数事件名以on为前缀;
  • 3、当为同一对象的相同事件指定多个处理程序时,执行顺序和DOM2相反,IE中以添加它们的相反顺序执行。

例如:

6c62a7e2513a7465a5a873220f3f5dac
...
8019067d09615e43c7904885b5246f0a
  84f07fc1f7167f067b3f15a898dda831
2cacc6d41bbb37262a98f745aa00fbf0

执行结果:

handle2!
true

handle1!
true

跨浏览器支持

虽然可以使用屏蔽浏览器差异的JS库,实际上,我们自己编写一个跨浏览器兼容的事件处理代码并不是一件困难的事情,同时更有利于我们对原生JavaScript的学习理解。我们使用一个习惯上称为EventUtil的对象来进行跨浏览器事件处理:

var EventUtil = {
    addEventHandler : function(element, eventType,        handler) {
        if(element.addEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.attachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = handler;
        }
    },

    removeEventHandler : function(element, eventType, handler) {
        if(element.aremoveEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.detachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = null;
        }
    }
}

为了保证事件处理代码能够在大多数浏览器中一致地运行,我们这里只关注冒泡阶段。以上代码使用浏览器能力检测,首先检测是否支持DOM2级方法addEventListener和removeEventListener,如果支持则使用该方法;如果不支持该方法,检测是否是IE8级更早版本的attachEvent或detachEvent方法,若支持则使用该方法;如果对以上2种方法都不支持,则使用DOM0级方法。要注意,DOM0级对每个事件只能指定一个事件处理程序。

以上对象使用示例如下:

var btn1 = document.getElementById("btn1");var handle1 = function() {
    alert("handle1!" + "\n" + (this === window));
};var handle2 = function() {
    alert("handle2!"+ "\n" + (this === window));
};
EventUtil.addEventHandler(btn1, "click", handler1);
EventUtil.addEventHandler(btn1, "click", handler2);

EventUtil.removeEventHandler(btn1, "click", handler2);

五、事件对象

在触发某个事件时,会产生一个event对象。该对象中包含与事件有关的信息。例如触发事件的元素、事件的类型、与特定事件相关的如鼠标位置信息等。

  • 1、DOM事件对象
  • 2、IE事件对象与跨浏览器事件对象

1、DOM事件对象

不论使用DOM0级还是DOM2级方法指定事件处理程序,事件触发时都会自动将一个event对象传入事件处理程序,例如:

var btn1 = document.getElementById("btn1");

btn1.onmouseover = function(evnt) {
    alert(evnt.type);
}var handle = function(evnt) {
    alert(evnt.type);
};
btn1.addEventListener("click", handle, false);

以上是一个简单的event对象的示例。event对象中的type属性是一个只读字符串属性,其中包含着事件的类型。例如我们上例中的click和onmouseover。event对象中包含有大量的有关事件的属性和方法(例如event.stopPropagation()方法可用于停止事件在捕获或者冒泡阶段的继续传播,preventDefault()方法会取消阻止事件的行)在此就不一一列举了。其中常用的如下:

属性/方法 值类型 读写 描述
currentTarget Element readonly 事件处理程序当前正在处理的元素
target Element readonly 事件的目标
type String readonly 触发事件的类型
preventDefault Function readonly 取消事件默认行为,如链接的默认行为就是被单击时跳转到href指定的url
stopPropagation Function readonly 取消事件进一步冒泡或捕获

2、IE事件对象与跨浏览器事件对象

IE事件对象

在IE中,当使用DOM0级指定事件处理程序时,event对象被认为是window的一个属性,例如获取鼠标点击坐标的代码:

var mouseLoc = function() {
    var loc = "x: " + window.event.screenX + "\n" +              "y: " + window.event.screenY;
    alert(loc);
};

当使用attachEvent()方法指定事件处理程序时,event对象会被作为参数传入事件处理程序,我们将以上的代码重写:

var mouseLoc = function(event) {
    var loc = "x: " + event.screenX + "\n" +              "y: " + event.screenY;
    alert(loc);
};
btn1.attachEvent("onclick",  mouseLoc);

IE中event对象的相关属性方法:

属性/方法 值类型 读写 描述
cancelBubble Boolean read/write 默认为false,置为true时取消事件冒泡(同DOM中stopPropagation)
returnValue Boolean read/write 默认为true,设为false取消事件默认行为(同DOM中preventDefault)
srcElement Element readonly 事件目标
type String readonly 事件类型

跨浏览器事件对象

解决跨浏览器问题的思路是一贯的,我们可以对浏览器进行能力检测,这里我们对上面的EventUtil对象进行扩展,对我们学习原生JS,这是一个很漂亮的对象:

var EventUtil = {
    addEventHandler : function(element, eventType, handler) {
        if(element.addEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.attachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = handler;
        }
    },

    removeEventHandler : function(element, eventType, handler) {
        if(element.aremoveEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.detachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = null;
        }
    },

    getEvent: function (event) {
        return event ? event : window.event;
    },

    getTarget: function (event) {
        return event.target || event.srcElement;
    },

    preventDefault: function (event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },

    stopPropagation: function (event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubbles = true;
        }
    },

    getRelatedTarget: function (event) {
        if (event.relatedTarger) {            return event.relatedTarget;
        } else if (event.toElement) {            return event.toElement;
        } else if (event.fromElement) {            return event.fromElement;
        } else { return null; }
    }
}

【相关推荐:javascript学习教程

Das obige ist der detaillierte Inhalt vonEreignis-Bubbling und Zeiterfassung von JavaScript-Ereignissen (Zusammenfassungsfreigabe). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen
Vorheriger Artikel:Was bedeutet das in jqueryNächster Artikel:Was bedeutet das in jquery