Maison >interface Web >js tutoriel >Explication détaillée de la délégation d'événements Javascript

Explication détaillée de la délégation d'événements Javascript

巴扎黑
巴扎黑original
2017-07-24 16:02:481255parcourir

Cause :

1. Il s'agit d'un type de question classique pour les entretiens frontaux. Il est toujours utile de demander à vos partenaires de travail de le vérifier

2. En fait, je ne l'ai jamais compris. J'écris ceci d'abord comme rappel, et deuxièmement comme référence pour d'autres amis qui le savent mais ne savent pas pourquoi

Aperçu :

Quoi ? Et la délégation événementielle ? Il porte également un nom appelé proxy d'événement. En termes de programmation JavaScript avancée : la délégation d'événements utilise le bouillonnement d'événements pour gérer tous les événements d'un certain type en spécifiant un seul gestionnaire d'événements. Alors qu’est-ce que cela signifie ? Les experts sur Internet utilisent essentiellement le même exemple lorsqu'ils parlent de délégation d'événements, qui consiste à prendre une livraison express pour expliquer ce phénomène. J'y ai réfléchi attentivement et j'ai trouvé que cet exemple est vraiment approprié. Je ne penserai pas à d'autres exemples pour l'expliquer. Laissez-moi cueillir quelques fleurs à offrir à Bouddha. Regardons de plus près ce que signifie la délégation événementielle :

Trois collègues devraient recevoir une livraison express lundi. Il existe deux manières de signer pour la livraison express : l'une consiste à avoir trois personnes attendant la livraison express à la porte de l'entreprise ; l'autre consiste à confier au réceptionniste la signature en votre nom ; En réalité, nous utilisons majoritairement la solution confiée (l’entreprise ne tolérera pas autant de salariés devant la porte attendant une livraison express). Une fois que la MM à la réception aura reçu la livraison express, elle déterminera qui est le destinataire, puis signera selon les exigences du destinataire et paiera même en son nom. Un autre avantage de cette solution est que même si de nouveaux employés arrivent dans l'entreprise (peu importe leur nombre), la réception MM vérifiera l'envoi express envoyé aux nouveaux employés et le signera en leur nom.

Il y a en fait deux niveaux de signification ici :

Premièrement, les collègues de la réception peuvent désormais signer pour cela, c'est-à-dire que le nœud dom existant dans le programme a des événements

;

Deuxièmement, les nouveaux employés peuvent également être signés par la réception MM, c'est-à-dire que le nœud dom nouvellement ajouté au programme propose également des événements.

Pourquoi utiliser la délégation d'événements :

De manière générale, le DOM doit avoir un gestionnaire d'événements, et nous définirons simplement le gestionnaire d'événements directement s'il y a de nombreux DOM qui doivent être ajoutés. Qu’en est-il de la gestion des événements ? Par exemple, nous avons 100 li, et chaque li a le même événement de clic. Peut-être utiliserons-nous une méthode de boucle for pour parcourir tous les li, puis leur ajouter des événements. Quel en sera l'impact ?

En JavaScript, le nombre de gestionnaires d'événements ajoutés à la page sera directement lié aux performances globales de fonctionnement de la page, car plus elle doit interagir en permanence avec le nœud dom, plus le dom est accédé. plus il est probable que le navigateur redémarre. Plus vous dessinez et réorganisez, plus le temps de préparation interactive de la page entière sera long. C'est pourquoi l'une des principales idées de l'optimisation des performances est de réduire les opérations DOM ; si vous souhaitez utiliser la délégation d'événements, toutes les opérations seront placées dans un programme js, l'opération avec le dom ne nécessite d'interagir qu'une seule fois, ce qui peut réduire considérablement le nombre d'interactions avec le dom et améliorer les performances

;

Chaque fonction est un objet, et l'objet l'occupera Mémoire, plus il y a d'objets, plus l'utilisation de la mémoire est importante, et naturellement les performances seront moins bonnes (pas assez de mémoire est un défaut, haha ​​Par exemple,). les 100 li ci-dessus occuperont 100 espaces mémoire. Si c'est 1 000, 10 000, je ne peux que dire haha ​​si nous utilisons la délégation d'événement, alors nous ne pouvons opérer que sur l'objet de son parent (s'il n'y a qu'un seul parent), donc. nous n'avons besoin que d'un espace mémoire, cela économise beaucoup et les performances seront naturellement meilleures.

Principe de la délégation d'événements :

La délégation d'événements est mise en œuvre en utilisant le principe de bouillonnement des événements. Qu'est-ce que le bouillonnement d'événements ? Autrement dit, l'événement commence à partir du nœud le plus profond, puis se propage progressivement vers le haut. Par exemple : il existe une telle arborescence de nœuds sur la page, div>ul>li>a; a, alors cet événement sera Il sera exécuté couche par couche. La séquence d'exécution est a>li>ul>div Il existe un tel mécanisme. Ensuite, nous ajoutons un événement de clic au div le plus externe. , et un clic interne sur les événements, ils feront des bulles vers le div le plus externe, il sera donc déclenché. Il s'agit d'une délégation d'événement, qui délègue à leurs parents l'exécution d'événements en leur nom.

Comment mettre en œuvre la délégation d'événement :

Enfin, nous sommes arrivés au cœur de cet article, haha, avant d'introduire la méthode de délégation d'événement, jetons un œil à un exemple de méthode générale :

Les nœuds enfants implémentent la même fonction :


        
  • 111
  •     
  • 222
  •     
  • 333
  •     
  • 444
Pour réaliser la fonction, cliquez sur li, et 123 apparaît :

Explication détaillée de la délégation dévénements Javascript
window.onload = function(){
    var oUl = document.getElementById("ul1");
    var aLi = oUl.getElementsByTagName('li');
    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/22e3a06a99eaee066d9e0282007809c3-1.gif" alt="Explication détaillée de la délégation dévénements Javascript"></span></div></ali.length>
La signification du code ci-dessus est très simple, je crois. beaucoup de gens l'ont implémenté de cette façon. Voyons combien de fois il est implémenté. Pour les opérations DOM, vous devez d'abord trouver ul, puis parcourir li, puis lorsque vous cliquez sur li, vous devez retrouver la position du li cible avant de vous. peut effectuer l'opération finale. Vous devez trouver li une fois pour chaque clic

Alors que se passera-t-il si nous utilisons la délégation d'événement ?

window.onload = function(){
    var oUl = document.getElementById("ul1");
   oUl.onclick = function(){
        alert(123);
    }
}

 

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

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

Explication détaillée de la délégation dévénements Javascript

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);
    }
  }
}

Explication détaillée de la délégation dévénements Javascript

 

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

 

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

<div>
        <input>
        <input>
        <input>
        <input>
    </div>
Explication détaillée de la délégation dévénements Javascript
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('选择');
            }
            
        }
Explication détaillée de la délégation dévénements Javascript

 

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

Explication détaillée de la délégation dévénements Javascript
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;
                    }
                }
            }
            
        }
Explication détaillée de la délégation dévénements Javascript

 

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

 

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

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

Explication détaillée de la délégation dévénements Javascript
<input>
    
            
  • 111
  •         
  • 222
  •         
  • 333
  •         
  • 444
  •     
Explication détaillée de la délégation dévénements Javascript

 

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

 

Explication détaillée de la délégation dévénements Javascript
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="Explication détaillée de la délégation dévénements Javascript"></span></div></ali.length>

 

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

Explication détaillée de la délégation dévénements Javascript
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="Explication détaillée de la délégation dévénements Javascript"></span></div></ali.length>

 

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

Explication détaillée de la délégation dévénements Javascript
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);
            };
        }
Explication détaillée de la délégation dévénements Javascript

 

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

 

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

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn