Cet article n'empêche pas vraiment les éléments enfants de l'élément event de bouillonner...
Il juge simplement lorsque l'élément enfant passe à l'élément événement pour déterminer si l'événement doit être déclenché, oh... non, il devrait s'agir de savoir s'il faut exécuter les opérations pertinentes dans la fonction événement...
Tout d'abord, vous pouvez cliquer ici : Occurrence du problème
Remarque : l'événement mouseover/out dans jquery a également ce problème
Solution 1 :
Sous IE, il existe des événements mouseenter et mouseleave pour remplacer mouseover et mouseout.
Il existe de nombreuses opinions sur Internet selon lesquelles ces deux événements ne sont pris en charge que par IE et non par d'autres navigateurs.
Mais les dernières versions de Firefox et de Google prennent en charge mouseenter et mouseleave ! ! ! ! !
De plus, la plage de support d'IE est : [ie5, nous ne devrions donc pas pulvériser IE...
Testé avec d'autres navigateurs :
Mouseenter et mouseleave ne sont pas pris en charge dans Firefox/3.6.28. On ne sait pas quelle version de Firefox prendra en charge ces deux événements...
.Il n'est pas pris en charge dans Opera9.50 Alpha et Opera9.00 Beta. En fait, il n'est pas nécessaire de tester Opera pour le moment. La dernière version d'Opera est basée sur le noyau webkit...
La version inférieure de Google n'a pas été testée...
Bien sûr, ces anciennes versions de navigateurs peuvent fondamentalement être ignorées, cela devrait donc être la meilleure solution : utilisez les événements mouseenter et mouseleave pour remplacer mouseover et mouseout.
Pour des exemples de ces deux événements, cliquez ici : mouseenter et mouseleave
Remarque : jquery propose également des événements mouseenter et mouseleave, qui sont compatibles avec tous les navigateurs.
Solution 2 :
La méthode ci-dessus n'est pas prise en charge par les anciennes versions de Firefox et de Google. Si vous souhaitez une plus grande compatibilité, vous pouvez continuer à lire ci-dessous
.Nous utilisons var reltg = e.ratedTarget ? e.ratedTarget : e.type == 'mouseout' ? Utilisez ensuite la relation entre cet élément lié à l'événement et l'élément événementiel (la relation incluse) pour déterminer s'il convient d'effectuer un traitement des événements associés.
Pour l'événement mouseout, reltg est le nœud dans lequel le pointeur de la souris entre lorsqu'il quitte la cible.
Pour l'événement mouseover, reltg est le nœud que le pointeur de la souris quitte lorsqu'il se déplace vers le nœud cible.
Dans la fonction d'événement mouseout de li, si reltg est l'élément enfant de li, nous n'avons pas besoin d'exécuter les opérations pertinentes. Si reltg est l'élément parent de li, nous exécuterons les opérations pertinentes.
Nous pouvons juger de la relation d'inclusion entre li et reltg grâce à la fonction isMouseLeaveOrEnter suivante :
//判断事件相关元素与li的关系 如果事件相关元素为li的子元素就返回false 反之返回true function isMouseLeaveOrEnter(e, handler) { if (e.type != 'mouseout' && e.type != 'mouseover') return false; var reltg = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement; while (reltg && reltg != handler) reltg = reltg.parentNode; return (reltg != handler); }; Li.onmouseout = function(e) { e = e||window.event; if (isMouseLeaveOrEnter(e,this)) { //运行相关操作 }; }
L'inconvénient évident de cette méthode est que tous les éléments parents doivent être parcourus dans isMouseLeaveOrEnter, ce qui pose un problème de performances
Solution trois :
Cette méthode a la même idée que la deuxième méthode, sauf que nous utilisons compareDocumentPosition/contains pour déterminer la relation de confinement entre li et reltg, ce qui optimise les problèmes de performances causés par le parcours de tous les éléments parents dans la deuxième méthode.
Regardons directement le code :
//判断node是否为parent的子元素 //if node == parent 也会返回true function contains(parent, node) { if(parent.compareDocumentPosition){ //ff var _flag = parent.compareDocumentPosition(node); return (_flag == 20 || _flag == 0)? true : false; }else if(parent.contains){ //ie return parent.contains(node); } }; Li.onmouseout = function(e) { e = e||window.event; var relatedEle = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement if (!contains(this, relatedEle)) { show.innerHTML=show.innerHTML+'0'; } }
compareDocumentPosition() compare deux nœuds et renvoie un entier décrivant leur position dans le document.
La valeur de retour peut être :
1 : Ce n’est pas grave, les deux nœuds n’appartiennent pas au même document.
2 : Le premier nœud (P1) est situé derrière le deuxième nœud (P2).
4 : Le premier nœud (P1) est positionné devant le deuxième nœud (P2).
8 : Le premier nœud (P1) est situé à l'intérieur du deuxième nœud (P2).
16 : Le deuxième nœud (P2) est situé à l'intérieur du premier nœud (P1).
32 : Il n'y a pas de relation, ou les deux nœuds sont deux attributs d'un même élément.
Remarque : la valeur de retour peut être une combinaison de valeurs. Par exemple, renvoyer 20 signifie que p2 est à l’intérieur de p1 (16) et que p1 est avant p2 (4).
Et [ie8- ne prend pas en charge la méthode compareDocumentPosition(). Vous devez utiliser contain à la place. La méthode compareDocumentPosition() est si puissante qu'elle est utilisée pour déterminer si nodeB est inclus dans un autre nodeA : nodeA.contains( nodeB. )
Ce qui précède représente l’intégralité du contenu de cet article, j’espère que vous l’aimerez tous.