2011-12-15 2 views
1

C'est un simple menu cacher/afficher: Lorsque vous passez la souris sur un élément de liste, le script affiche toutes les listes non ordonnées qui sont enfants de cet élément de liste, puis affiche. Le CSS met cette sous-liste à la droite immédiate de l'élément de liste plané. Lorsque vous quittez la souris, il masque à nouveau cette liste non ordonnée.jQuery hover() masquer/afficher provoquant le rebond

Le code HTML:

<div class="menu-header-category-menu-container"> 
    <ul id="menu-header-category-menu" class="menu"> 
    <li id="menu-item-58"><a href="?cat=3">Parent Category I</a> 
     <ul class="sub-menu"> 
     <li id="menu-item-59"><a href="?cat=6">Child Category I</a></li> 
     <li id="menu-item-60"> 
      <a href="?cat=7">Child Category II</a> 
      <ul class="sub-menu"> 
      <li id="menu-item-61"><a href="?cat=9">Grandchild Category I</a></li> 
      </ul> 
     </li> 
     </ul> 
    </li> 
    <li id="menu-item-62"><a href="?cat=4">Parent Category II</a></li> 
    <li id="menu-item-63"> 
     <a href="?cat=5">Parent Category III</a> 
     <ul class="sub-menu"> 
     <li id="menu-item-64"><a href="?cat=8">Child Category III</a></li> 
     </ul> 
    </li> 
    <li id="menu-item-57"><a href="?cat=1">Uncategorized</a></li> 
    </ul> 
</div> 

Le CSS:

li { 
    width: 150px; 
    border: 1px solid black; 
    background-color: aqua; 
    list-style-type: none; 
    position: relative; 
} 

ul.sub-menu { 
    position: absolute; 
    left: 110px; 
    top: 0px; 
    display: none; 
} 

Le JavaScript:

$(document).ready(function() { 
    $('li').hover(
     function() { $(this).children('ul').show('slow'); }, 
     function() { $(this).children('ul').hide('slow'); } 
    ); 
}); 

Il fonctionne principalement comme il se doit. Sauf si vous déplacez la souris au-dessus de l'élément de la liste et la laissez dans l'espace où la sous-liste doit apparaître (avant que la sous-liste ne finisse de s'afficher), vous la coincez dans une boucle répétée show/hide/show/hide le curseur de la souris.

J'ai essayé de résoudre ce problème en utilisant setTimeout() dans la fonction de l'argument mouseover et dans la fonction de l'argument mouseout. J'ai également essayé d'utiliser des conditions pour vérifier si la sous-liste est cachée dans ces arguments. Je ne vois aucune différence de performance.

Toute personne

+0

Essayez liant le gestionnaire mouseover à l'ancre au lieu de l'élément de liste. J'ai le sentiment que tout va bien se passer. – lsuarez

+0

Je peux voir la logique dans cela (puisque le li contient le sous-menu) mais, cela ne fera pas disparaître le sous-menu lorsque vous quittez l'ancre (ce que vous feriez si vous deviez cliquer quelque chose dans le sous-menu) –

+0

Derp. Regardé avant que je saute, ce n'est pas vraiment la solution, mais j'ai le sentiment que c'est la source de la question en quelque sorte. Il semble que le survol de la souris sur un élément de la liste devrait masquer tous les sous-menus visibles au niveau actuel, puis afficher le sien, avec un mouseout sur le niveau supérieur ul pour masquer tous les sous-menus visibles. – lsuarez

Répondre

1

Ceci est un problème commun, consultez Hover Intent

+0

c'est intéressant. J'ai utilisé Hover Intent, et il est plus difficile de déclencher accidentellement le bug, mais si j'ai l'intention de le faire, je peux le faire. Je me demande si c'est quelque chose que je vais devoir vivre avec. –

+0

J'ai travaillé un peu plus, et l'utilisation de l'argument timeout a rendu presque impossible la duplication. Je suis à peu près sûr que je ne serai plus dérangé par ça. À votre santé! –

0

Je pense qu'il attire votre événement mouseout avant d'afficher le sous-menu. Essayez de modifier/masquer la vitesse pour accélérer. Mais ce n'est pas une solution.

+0

ouais, la chose malheureuse à ce sujet est le problème d'apparence. –

0

Ce code évitera également les multiples rebondir

var myVar; 
$(".liveUser").on({ 
     mouseenter: function() { 
     myVar = setTimeout(function(){ //optional delay 
      //$(".userDetail").stop().hide().fadeIn(); 
       $(".userDetail").stop().hide().show(); 
       }, 400); 
     }, 
     mouseleave: function() { 
      clearTimeout(myVar); 
      //$(".userDetail").stop().fadeOut(); 
      $(".userDetail").stop().hide(); 
     } 
    });