Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung des Ereignismodells in JavaScript (Codebeispiel)

Detaillierte Erläuterung des Ereignismodells in JavaScript (Codebeispiel)

不言
不言nach vorne
2018-11-21 11:47:411597Durchsuche
Dieser Artikel enthält eine detaillierte Erklärung (Codebeispiel) des Ereignismodells in JavaScript. Ich hoffe, dass er für Freunde hilfreich ist.

Veranstaltung

Benutzerinteraktion mit Webseiten wird zunächst durch Ereignisse realisiert, um die Serverlast zu teilen. Erst auf der DOM2-Ebene begannen Netscape und IE, ihre eigenen zu haben API-Spezifikationen.

In Bezug auf den Ereignisauslösemechanismus glauben beide Unternehmen, dass der Auslösemechanismus der Seite nicht nur das Ereignis des aktuellen Zielelements auslöst, wenn auf ein bestimmtes Element geklickt wird.

Zum Beispiel: Die Seite hat mehrere konzentrische Kreise. Wenn Sie auf den innersten Kreis klicken, klicken Sie tatsächlich auf die Kreise, die die Außenseite dieses Kreises umfassen. In diesem Punkt sind sich die beiden Unternehmen einig, die Ausbreitungssequenz des Ereignisstroms wird jedoch mit zwei unterschiedlichen Lösungen umgesetzt, nämlich Event Bubbling und Event Capture.

1. Event-Bubbling

Der IE-Browser unterstützt seit der alten Version immer den Event-Bubbling-Mechanismus Zur Verbreitung unspezifischer Elemente.

wird vom Zielelement an das übergeordnete Element weitergegeben.

    <div>
        <div></div>
    </div>
    <script>
    function childEventHandler(event) {
        console.log(this);
        console.log("child 被点击了");
    }
    function parentEventHandler(event) {
        console.log(this);
        console.log("parent 被点击了");
    }
    function bodyEventHandler(event) {
        console.log(this);
        console.log("body 被点击了");
    }
    function htmlEventHandler(event) {
        console.log(this);
        console.log("html 被点击了");
    }
    function documentEventHandler(event) {
        console.log(this);
        console.log("document 被点击了");
    }
    function windowEventHandler(event) {
        console.log(this);
        console.log("window 被点击了");
    }
    var bodyEl = document.getElementsByTagName("body")[0];
    var htmlEl = document.getElementsByTagName("html")[0];
    var win = window;
    var parentEl = document.getElementById("parent");
    var childEl = document.getElementById("child");
    childEl.onclick = childEventHandler;
    parentEl.onclick = parentEventHandler;
    bodyEl.onclick = bodyEventHandler;
    htmlEl.onclick = htmlEventHandler;
    document.onclick = documentEventHandler;
    win.onclick = windowEventHandler;
    </script>

Wie in der Abbildung unten gezeigt, wird der Ereignisfluss vom untergeordneten Objekt zum Fensterobjekt weitergeleitet, wenn auf das Element mit der ID „Kind“ geklickt wird. Alle modernen Browser unterstützen das Event-Bubbling.

2. Ereigniserfassung Detaillierte Erläuterung des Ereignismodells in JavaScript (Codebeispiel)Die von Netscape gesteuerte Ereigniserfassung ist genau das Gegenteil von Ereignissprudeln. Der Ereignisstrom wird zunächst von unspezifischen Elementen ausgelöst und breitet sich dann auf bestimmte Elemente aus. Kurz gesagt, es wird vom übergeordneten Element an das Zielelement weitergegeben.

Detaillierte Erläuterung des Ereignismodells in JavaScript (Codebeispiel)Da die Ereigniserfassung ab IE 9 unterstützt wird und nicht mit älteren Browserversionen kompatibel ist, wird sie von weniger Menschen verwendet.

3. Ereignisfluss

DOM legt fest, dass Ereignisse drei Phasen umfassen: Ereigniserfassung, Zielphase und Ereignissprudeln.

Browser ab IE 9 legen fest, dass die Reihenfolge des Ereignisflusses zuerst die Ereigniserfassung ist, das Ereignis abgefangen wird, dann in der Zielphase ist, das eigentliche Ziel das Ereignis empfängt und schließlich das Ereignis in die Luft sprudelt . Sie können überprüfen, ob diese Stufe auf Ereignisse reagiert.

Nehmen wir als Beispiel das vorherige untergeordnete Element: Bis das untergeordnete Element das Ereignis empfängt (vom Fenster zum übergeordneten Element), ist es die Phase der Ereigniserfassung. Wenn es das untergeordnete Element erreicht, wird das Ereignis zu diesem Zeitpunkt verarbeitet und dann zum Fensterobjekt übertragen. Das Ereignis kann auch während der Bubbling-Phase verarbeitet werden. Basierend auf den Merkmalen des Event-Bubblings, das Ereignisse verarbeiten kann, wird der damit verbundene Ereignisdelegierungsmechanismus später erörtert. Detaillierte Erläuterung des Ereignismodells in JavaScript (Codebeispiel)

4. Ereignisbindung

Es gibt drei Formen der Bindung zwischen HTML und Ereignissen:

1. 
<div></div>

2. 

var childEl = document.getElementById("child");
childEl.onclick = function() {
    console.log('hello');
}

3. 
var childEl = document.getElementById("child");
childEl.addEventListener('click', function() {
    console.log('hello');
}, false);

JavaScript Es handelt sich um eine Single-Thread-Sprache. Wenn ein Ereignis für ein Element ausgelöst wird, durchsucht es die Ereigniswarteschlange, um festzustellen, ob eine Funktion an das Ereignis gebunden ist Die Funktion wird in die Ereigniswarteschlange gestellt. Warten Sie, bis das Haupt-Thread-Ereignis nach der Ausführung ausgeführt wird.

Die erste Bindung des obigen Codes schreibt das Ereignis in HTML und die Leistung und das Verhalten sind nicht entkoppelt. Es wird nicht empfohlen, Code auf diese Weise zu schreiben.

Die zweite Art der Bindung bindet Ereignisse an Elementobjekte. Mit dieser Schreibmethode können Ereignisse hauptsächlich einfach überschrieben werden. Detaillierte Erläuterung des Ereignismodells in JavaScript (Codebeispiel)Die dritte Bindung, zunächst einmal ist der dritte Parameter ein boolescher Wert, der Standardwert ist false, was bedeutet, dass der Event-Handler in der Event-Bubbling-Phase aufgerufen wird, wenn er wahr ist, bedeutet dies, dass der Event-Handler aktiviert ist wird in der Funktion „Ereigniserfassung“ aufgerufen.

Wenn wir ein Ereignis verarbeiten möchten und die Ereignisbindung des Elements nicht mehr verarbeiten möchten, sollten wir die Ereignisbindung des Elements auf leer setzen, da es sonst leicht zu Speicherlecks kommen kann.

第一种写法:
childEl.onclick = null;


第三种写法:
function eventHandler() {
    console.log('hello');
}

childEl.addEventListener('click', eventHandler, false);

childEl.removeEventListener('click', eventHandler, false);

Ereignisdelegation (Ereignis-Proxy)

Die Ereignisdelegation nutzt die sprudelnde Natur von Ereignissen und breitet sich dann auf unspezifische Elemente aus.

Wenn es eine Liste gibt, löst jeder Klick auf ein Listenelement den Ereignishandler aus. Wenn Sie Ereignisse einzeln an die Elemente binden, ist die Effizienz natürlich definitiv nicht gut.

Gleichzeitig kann es beim Hinzufügen eines neuen Elements dazu kommen, dass das Ereignis nicht erfolgreich gebunden wird. Werfen wir einen Blick darauf:


        
  • menu-1
  •     
  • menu-2
  •     
  • menu-3
  •     
  • menu-4
<script> window.onload = function() { var menu = document.getElementById("menu"); var item = menu.getElementsByClassName(&#39;menu-item&#39;); for (var i = 0; i < item.length; i++) { item[i].onclick = (function(i) { return function() { console.log(i); } }(i)) } var addBtnEl = document.getElementById("addBtn"); addBtnEl.onclick = function() { var newEl = document.createElement(&#39;li&#39;); newEl.innerHTML = "menu-new" menu.appendChild(newEl); } } </script> Das neu hinzugefügte Menü-Neu. Wenn Sie darauf klicken, erfolgt keine Reaktion, was darauf hinweist, dass das Ereignis nicht daran gebunden ist, wir das Ereignis jedoch nicht an dieses neue Element binden möchten Jedes Mal, wenn ein neues Element hinzugefügt wird, sollte die Wiederholung ineffizienter Arbeiten vermieden werden.

我们通过事件委托的思路来想,事件流的传播,目标元素本身依然会有事件,但同时,冒泡出去后,更高层次的 dom 也能处理事件程序。那么,我们只需要给高层次节点绑定事件,通过判断具体是触发的哪个子节点,再做相应的事件处理。


        
  • menu-1
  •     
  • menu-2
  •     
  • menu-3
  •     
  • menu-4
<script> window.onload = function() { var menu = document.getElementById("menu"); menu.onclick = function(event) { var e = event || window.event; var target = e.target || e.srcElement; console.log(e); switch (target.textContent) { case "menu-1": console.log("menu-1 被点击了"); break; case "menu-2": console.log("menu-2 被点击了"); break; case "menu-3": console.log("menu-3 被点击了"); break; case "menu-4": console.log("menu-4 被点击了"); break; case "menu-new": console.log("menu-new 被点击了"); break; } } var addBtnEl = document.getElementById("addBtn"); addBtnEl.onclick = function() { var newEl = document.createElement(&#39;li&#39;); newEl.innerHTML = "menu-new" menu.appendChild(newEl); } } </script>

menu 列表的每个子菜单元素的事件都能正确响应,新增的 menu-new 同样也能正确响应事件。

事件委托的好处在于,我们不用给每个元素都一一地手动添加绑定事件,避免重复低效的工作。

其次,事件委托更少得获取 dom, 初始化元素对象和事件函数,能有效减少内存占用。

每当将事件程序指定给元素时,html 代码和 js 代码之间就建立了一个连接,这种连接越多,网页就执行起来越慢,所以事件委托能有效减少连接树,提高网页性能。

总结

用户与网页的交互是通过事件进行的,事件模型分为事件冒泡和事件捕获,事件冒泡的兼容性更好,应用更广,同时通过事件冒泡,可以建立事件委托,提升网页性能。

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Ereignismodells in JavaScript (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen