Bonjour,

J'ai fait une topbar qui se déroule quand la souris passe sur une flèche, tant que la flèche reste sur la topbar, elle reste visible, mais dès que la souris quitte la topbar, celle-ci se cache après un temps de 10s par exemple, pour le moment ça fonctionne mais il y a des bugs, Voici le code html :

<div class="topbar">
       <nav class="navhidden" id="options_bar">
         <span class="content-right">
          <a href="#" class="link">Sign In</a>
          <h4 class="tel_support"><span class="glyphicon glyphicon-phone-alt"></span> Nous contacter</h4>
          </span>
         <span class="content-left">

         </span>
       </nav>
       <span class="plus">
        <a href="#"><span class="glyphicon glyphicon-chevron-down"></span></a>
      </span>
    </div>

Et le script jquery :

/**
     * Bar d'options et de recherche
     **/
     var optionsBar = $('#options_bar');
     var topbar = $('.topbar');
     var plus = $('#plus');
     var txtPlus = $('.plus');
     //optionsBar.hide();
     function initTopbarDown(time){
        optionsBar.slideDown({
            duration: 1000,
            easing: 'jswing'
        });
        $('.plus span').removeClass('glyphicon glyphicon-chevron-down');
        $('.plus span').addClass('glyphicon glyphicon-chevron-up');
     }
     $('.plus').mouseover(function(){
        initTopbarDown(500);
        // La souris est sur l'élément
        optionsBar.bind('mouseenter', function(){
            initTopbarDown(1000);
            //clearTimeout(vartimeTopbar);
            //vartimeTopbar = null;
        }).bind('mouseleave', function(){
            setTimeout(function(){
                optionsBar.slideUp({
                    duration: 1000,
                    easing: 'jswing'
                });
            }, 2000);
            $('.plus span').removeClass('glyphicon glyphicon-chevron-up');
            $('.plus span').addClass('glyphicon glyphicon-chevron-down');
        });
     });

Mon script comporte surment des bug, car déjà l'effet slideUp et slideDown ne fonctionne pas.

Merci d'avance pour vos réponses

4 réponses


salut, un jsfiddle pour qu'on voit le problème ?

Problème de lien, le voici : Fiddle

Je viens de regarder ton jsfiddle, et j'ai trouvé les erreurs,

  1. Dans ton JS

    easing : 'jswing' // à supprimer

  2. Dans ton css

    options_bar {
    display: none;
    margin-bottom: -1px; 
    transition: 0.5s // a supprimer

    }

Concernant ton code JS, il y a en effet des éléments qui sont améliorables.

  1. Attention au nom de variables, par convention je mets $ pour un objet et rien pour une valeur
    (ex : var $plus = $('.plus') mais var width = $plus.outerWidth() )

  2. Réutilise ces variables :

    // exemple
    $plus.find('span').addClass(...)

Cela permet de ne pas recréer l'objet en mémoire donc de gagner un peu en rapidité. Cela ne te semble pas visible comme ça car le code est petit mais lorsque tu travailles avec beaucoup de données, c'est une optimisation non négligable.

  1. chaine tes méthodes

    // exemple
    $plus.find('span').removeClass().addClass()

  2. Ne supprimes pas la classe 'glyphicon' car tu la réajoute après, aucune de ces deux actions ne sont nécessaires.

  3. Ce n'est pas une obligation mais je préfère utiliser un .on() que l'event direct,

    // exemple
    $(document)
    .on('mouseenter', '.plus', function(){
    })
    .on('mouseleave', '.plus', function() {
    });

La différence entre .on('mouseenter') et .mouseenter() est que dans le premier cas, le listener va se placer sur des éléments créés après le chargement du script alors que dans le second cas non, il faudra le rappeler. Pour plus de sureté, j'utilise toujours on() comme ça je ne me pose pas la question de savoir si le listener est placé ou non.

  1. Encore une possibilité d'amélioration mais non obligatoire, utiliser des events personnalisés

    var $document = $(document);
    // exemple
    $document
    .on('mouseenter', '.plus', function(){
    $document.trigger('menu-open');
    })
    .on('mouseleave', '.plus', function(){
    $document.trigger('menu-close');
    });
    $document
    .on('menu-open', function() {
    // faire le code habituel
    optionsBar.slideDown( ... )
    })
    .on('menu-close', function() {
    optionsBar.slideUp( ... )
    });

Cela te permet de pouvoir appeler tes events 'menu-open' et 'menu-close' avec d'autres éléments, cela permet d'avoir un code modulable et simple. Grâce à ça, je peux ouvrir le menu comme ceci :

$document.on('click', 'a.open-menu-link', function() {
    $document.trigger('menu-open');
});

Je ne te donne pas le code final pour que tu réfléchisses à mes propositions et que tu améliores ton code par toi même, je t'invite à reposter un jsfiddle une fois fait et nous reparlerons de cette itération.

Bon courage !