Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung der Javascript-Ereignisdelegation

Detaillierte Erläuterung der Javascript-Ereignisdelegation

巴扎黑
巴扎黑Original
2017-07-24 16:02:481180Durchsuche

Ursache:

1. Dies ist ein klassischer Fragetyp für Front-End-Interviews. Es ist immer noch hilfreich, Ihre Arbeitspartner zu bitten, sich das anzuschauen >2. Tatsächlich habe ich es nie herausgefunden, erstens als Erinnerung und zweitens als Referenz für andere Freunde, die es wissen, aber nicht wissen, warum;

Was ist mit der Delegation von Veranstaltungen? Es hat auch einen Namen namens Event-Proxy. In Bezug auf die erweiterte JavaScript-Programmierung: Die Event-Delegation verwendet Event-Bubbling, um alle Ereignisse eines bestimmten Typs zu verwalten, indem nur ein Event-Handler angegeben wird. Was bedeutet das also? Die Experten im Internet verwenden im Grunde das gleiche Beispiel, wenn sie über die Delegation von Ereignissen sprechen, um dieses Phänomen zu erklären. Ich habe sorgfältig darüber nachgedacht und festgestellt, dass mir dieses Beispiel nicht wirklich geeignet ist, es zu erklären Lassen Sie mich ein paar Blumen pflücken, um sie Buddha anzubieten. Schauen wir uns genauer an, was eine Veranstaltungsdelegation bedeutet:

Es wird erwartet, dass drei Kollegen am Montag eine Expresszustellung erhalten. Es gibt zwei Möglichkeiten, die Expresszustellung zu unterschreiben: Eine besteht darin, drei Personen an der Tür des Unternehmens auf die Expresszustellung warten zu lassen. In der Realität nutzen wir meist die anvertraute Lösung (das Unternehmen duldet nicht, dass so viele Mitarbeiter an der Tür stehen und nur auf die Expresszustellung warten). Nachdem die MM an der Rezeption die Expresszustellung erhalten hat, ermittelt sie, wer der Empfänger ist, unterschreibt dann entsprechend den Anforderungen des Empfängers und bezahlt die Lieferung sogar in ihrem Namen. Ein weiterer Vorteil dieser Lösung besteht darin, dass selbst wenn neue Mitarbeiter in das Unternehmen eintreten (egal wie viele), der MM an der Rezeption die an die neuen Mitarbeiter gesendete Expresszustellung überprüft und in ihrem Namen unterzeichnet.

Hier gibt es tatsächlich zwei Bedeutungsebenen:

Erstens können die Kollegen an der Rezeption jetzt dafür unterschreiben, das heißt, der vorhandene Dom-Knoten im Programm hat Ereignisse;

Zweitens können neue Mitarbeiter auch von der MM an der Rezeption angemeldet werden, d. h. der neu hinzugefügte Dom-Knoten im Programm hat auch Veranstaltungen.

Warum Ereignisdelegation verwenden:

Im Allgemeinen benötigt DOM einen Ereignishandler, und wir legen den Ereignishandler einfach direkt dafür fest, wenn viele DOMs hinzugefügt werden müssen Wie sieht es mit der Eventabwicklung aus? Zum Beispiel haben wir 100 Lis und jedes Li hat das gleiche Klickereignis. Vielleicht verwenden wir eine for-Schleifenmethode, um alle Lis zu durchlaufen und ihnen dann Ereignisse hinzuzufügen.

In JavaScript steht die Anzahl der der Seite hinzugefügten Ereignishandler in direktem Zusammenhang mit der Gesamtleistung der Seite, da sie ständig mit dem Dom-Knoten interagieren muss. Je häufiger Sie zeichnen und neu anordnen, desto länger ist die interaktive Bereitschaftszeit der gesamten Seite. Aus diesem Grund besteht eine der Hauptideen der Leistungsoptimierung darin, DOM-Vorgänge zu reduzieren. Wenn Sie die Ereignisdelegierung verwenden möchten, werden alle Vorgänge ausgeführt. Wenn Sie sie in ein JS-Programm einfügen, muss der Vorgang nur einmal mit dem Dom interagiert werden, was die Anzahl der Interaktionen mit dem Dom erheblich reduzieren und die Leistung verbessern kann

Jede Funktion ist ein Objekt, und das Objekt belegt es. Je mehr Objekte vorhanden sind, desto größer ist die Speichernutzung und natürlich wird die Leistung schlechter (nicht genügend Speicher ist ein Fehler, haha). Die oben genannten 100 li belegen 100 Speicherplätze. Wenn es 1.000 oder 10.000 ist, kann ich nur sagen, haha. Wenn wir die Ereignisdelegation verwenden, können wir nur das Objekt seines übergeordneten Elements bearbeiten Wir brauchen nur Speicherplatz, das spart viel und die Leistung wird natürlich besser sein.

Prinzip der Event-Delegation:

Die Event-Delegation wird nach dem Bubbling-Prinzip von Events umgesetzt. Was ist Event-Bubbling? Das heißt, das Ereignis beginnt am tiefsten Knoten und breitet sich dann schrittweise nach oben aus. Beispiel: Es gibt einen solchen Knotenbaum auf der Seite, div>ul>li>a; Fügen Sie beispielsweise ein Klickereignis zum innersten hinzu a, dann wird dieses Ereignis Schicht für Schicht ausgeführt. Die Ausführungssequenz ist a>li>div. Dann fügen wir dem äußersten div ein Klickereignis hinzu , und wenn Sie auf Ereignisse klicken, blasen sie bis zum äußersten Div, sodass es ausgelöst wird. Dies ist eine Ereignisdelegation, die ihre Eltern delegiert, Ereignisse in ihrem Namen auszuführen.

So implementieren Sie die Ereignisdelegation:

Endlich haben wir den Kernteil dieses Artikels erreicht, haha, bevor wir die Methode der Ereignisdelegation vorstellen, werfen wir einen Blick auf ein Beispiel einer allgemeinen Methode :

Die untergeordneten Knoten implementieren die gleiche Funktion:

Um die Funktion zu erreichen, klicken Sie auf li, und 123 wird angezeigt:


        
  • 111
  •     
  • 222
  •     
  • 333
  •     
  • 444

Detaillierte Erläuterung der Javascript-Ereignisdelegation
window.onload = function(){
    var oUl = document.getElementById("ul1");
    var aLi = oUl.getElementsByTagName('li');
    for(var i=0;i<ali.length> Die Bedeutung des obigen Codes ist meiner Meinung nach sehr einfach Viele Leute haben es auf diese Weise implementiert. Mal sehen, wie oft es implementiert wird. Für DOM-Operationen müssen Sie zuerst ul finden, dann li durchqueren und dann, wenn Sie auf li klicken, die Position des Ziels li erneut ermitteln Sie können den letzten Vorgang jedes Mal ausführen, wenn Sie klicken. <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"> Was passiert also, wenn wir die Ereignisdelegation verwenden? <img src="https://img.php.cn/upload/article/000/000/001/22e3a06a99eaee066d9e0282007809c3-1.gif" alt="Detaillierte Erläuterung der Javascript-Ereignisdelegation"></span></div></ali.length>

 

这里用父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发,当然,这里当点击ul的时候,也是会触发的,那么问题就来了,如果我想让事件代理的效果跟直接给节点的事件效果一样怎么办,比如说只有点击li才会触发,不怕,我们有绝招:

Event对象提供了一个属性叫target,可以返回事件的目标节点,我们成为事件源,也就是说,target就可以表示为当前的事件操作的dom,但是不是真正操作dom,当然,这个是有兼容性的,标准浏览器用ev.target,IE浏览器用event.srcElement,此时只是获取了当前节点的位置,并不知道是什么节点名称,这里我们用nodeName来获取具体是什么标签名,这个返回的是一个大写的,我们需要转成小写再做比较(习惯问题):

Detaillierte Erläuterung der Javascript-Ereignisdelegation

window.onload = function(){
  var oUl = document.getElementById("ul1");
  oUl.onclick = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    if(target.nodeName.toLowerCase() == 'li'){
         alert(123);
         alert(target.innerHTML);
    }
  }
}

Detaillierte Erläuterung der Javascript-Ereignisdelegation

 

这样改下就只有点击li会触发事件了,且每次只执行一次dom操作,如果li数量很多的话,将大大减少dom的操作,优化的性能可想而知!

 

上面的例子是说li操作的是同样的效果,要是每个li被点击的效果都不一样,那么用事件委托还有用吗?

<div>
        <input>
        <input>
        <input>
        <input>
    </div>
Detaillierte Erläuterung der Javascript-Ereignisdelegation
window.onload = function(){
            var Add = document.getElementById("add");
            var Remove = document.getElementById("remove");
            var Move = document.getElementById("move");
            var Select = document.getElementById("select");
            
            Add.onclick = function(){
                alert('添加');
            };
            Remove.onclick = function(){
                alert('删除');
            };
            Move.onclick = function(){
                alert('移动');
            };
            Select.onclick = function(){
                alert('选择');
            }
            
        }
Detaillierte Erläuterung der Javascript-Ereignisdelegation

 

上面实现的效果我就不多说了,很简单,4个按钮,点击每一个做不同的操作,那么至少需要4次dom操作,如果用事件委托,能进行优化吗?

Detaillierte Erläuterung der Javascript-Ereignisdelegation
window.onload = function(){
            var oBox = document.getElementById("box");
            oBox.onclick = function (ev) {
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLocaleLowerCase() == 'input'){
                    switch(target.id){
                        case 'add' :
                            alert('添加');
                            break;
                        case 'remove' :
                            alert('删除');
                            break;
                        case 'move' :
                            alert('移动');
                            break;
                        case 'select' :
                            alert('选择');
                            break;
                    }
                }
            }
            
        }
Detaillierte Erläuterung der Javascript-Ereignisdelegation

 

用事件委托就可以只用一次dom操作就能完成所有的效果,比上面的性能肯定是要好一些的 

 

 现在讲的都是document加载完成的现有dom节点下的操作,那么如果是新增的节点,新增的节点会有事件吗?也就是说,一个新员工来了,他能收到快递吗?

看一下正常的添加节点的方法:

Detaillierte Erläuterung der Javascript-Ereignisdelegation
<input>
    
            
  • 111
  •         
  • 222
  •         
  • 333
  •         
  • 444
  •     
Detaillierte Erläuterung der Javascript-Ereignisdelegation

 

现在是移入li,li变红,移出li,li变白,这么一个效果,然后点击按钮,可以向ul中添加一个li子节点

 

Detaillierte Erläuterung der Javascript-Ereignisdelegation
window.onload = function(){
            var oBtn = document.getElementById("btn");
            var oUl = document.getElementById("ul1");
            var aLi = oUl.getElementsByTagName('li');
            var num = 4;
            
            //鼠标移入变红,移出变白
            for(var i=0; i<ali.length><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://img.php.cn/upload/article/000/000/001/8e05a80ecdb75cfe19baae0423d6c017-11.gif" alt="Detaillierte Erläuterung der Javascript-Ereignisdelegation"></span></div></ali.length>

 

这是一般的做法,但是你会发现,新增的li是没有事件的,说明添加子节点的时候,事件没有一起添加进去,这不是我们想要的结果,那怎么做呢?一般的解决方案会是这样,将for循环用一个函数包起来,命名为mHover,如下:

Detaillierte Erläuterung der Javascript-Ereignisdelegation
window.onload = function(){
            var oBtn = document.getElementById("btn");
            var oUl = document.getElementById("ul1");
            var aLi = oUl.getElementsByTagName('li');
            var num = 4;
            
            function mHover () {
                //鼠标移入变红,移出变白
                for(var i=0; i<ali.length><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://img.php.cn/upload/article/000/000/001/8e05a80ecdb75cfe19baae0423d6c017-13.gif" alt="Detaillierte Erläuterung der Javascript-Ereignisdelegation"></span></div></ali.length>

 

虽然功能实现了,看着还挺好,但实际上无疑是又增加了一个dom操作,在优化性能方面是不可取的,那么有事件委托的方式,能做到优化吗?

Detaillierte Erläuterung der Javascript-Ereignisdelegation
window.onload = function(){
            var oBtn = document.getElementById("btn");
            var oUl = document.getElementById("ul1");
            var aLi = oUl.getElementsByTagName('li');
            var num = 4;
            
            //事件委托,添加的子元素也有事件
            oUl.onmouseover = function(ev){
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLowerCase() == 'li'){
                    target.style.background = "red";
                }
                
            };
            oUl.onmouseout = function(ev){
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLowerCase() == 'li'){
                    target.style.background = "#fff";
                }
                
            };
            
            //添加新节点
            oBtn.onclick = function(){
                num++;
                var oLi = document.createElement('li');
                oLi.innerHTML = 111*num;
                oUl.appendChild(oLi);
            };
        }
Detaillierte Erläuterung der Javascript-Ereignisdelegation

 

看,上面是用事件委托的方式,新添加的子元素是带有事件效果的,我们可以发现,当用事件委托的时候,根本就不需要去遍历元素的子节点,只需要给父级元素添加事件就好了,其他的都是在js里面的执行,这样可以大大的减少dom操作,这才是事件委托的精髓所在。

 

--------------------------------------------------华丽的分割线-------------- -----------------------------------------------------------------------------------------------------

在这里先感谢一下@苍茫大地NV 的提问,提的问题非常好!

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Javascript-Ereignisdelegation. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn