11490 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

J'utilise le code suivant pour un menu en Jquery. Le problème c'est qu'il y a clairement un conflit entre la fonction navOver et la fonction navOut quand le lien est du type a.active
En en effet je lui demande alors de toujours rester ouvert dans function navOut() alors que je demande aux autres menus de s'ouvrir dans navOver()

Est-ce qu'on ne peut pas signaler en JQuery que la fonction navOver est prioritaire : si je survole un lien il doit s'ouvrir même si dans navOur je demande au a.active de rester ouvert ?
Une autre solution ? Smiley lol


	 function navOver() { 
    //Add background color and image on hovered list item 
    $(this).css({ 'background' : '#1376c9 url(http://localhost/drupal/sites/all/themes/zen/zen_classic/images/background-menu-active.png) repeat-x'}); 
    //Show the subnav 
    $(this).find("span").show(); 
} 
 
function navOut() { 
    //Ditch the background 
    $(this).css({ 'background' : 'none'}); 
    //Hide the subnav 
    $(this).find("span").hide(); 
    navOver.apply($("ul#topnav li span a.active").parents("li"));  
} 
             
$(document).ready(function() { 
    $("ul#topnav li").hover(navOver, navOut); 
    navOver.apply($("ul#topnav li span a.active").parents("li"));  
});
    // -->

Modifié par Unbaraki (16 Aug 2009 - 20:36)
Bonjour,

Sur le principe déjà, rajouter des styles CSS en JavaScript quand on pourrait se contenter d'ajouter et de supprimer une classe (et de gérer le style exact dans la feuille de styles CSS), c'est pas terrible.

(Surtout quand l'URL est du genre http://localhost/, ça risque d'être drôle le passage en production si on oublie de modifier tel ou tel script JS. Smiley lol )

Du coup avec une classe, le fait de montrer le SPAN enfant (ou descendant) ça se gère aussi dans le CSS.

En fait, en lisant ce code, il semblerait que la seule chose qu'il fasse c'est dupliquer l'action d'un :hover en CSS, histoire d'être compatible avec IE6. Bon, je veux bien la question de la compatibilité IE6, mais ça se gère plus simplement comme ça:
$(document).ready(function() { 
  $("#topnav li").hover(
    function () {
      $(this).addClass('hover');
    }, 
    function () {
      $(this).removeClass('hover');
    }
  );
});


Par contre j'avoue ignorer ce qu'est censé faire:
navOver.apply($("ul#topnav li span a.active").parents("li"));

Je suis peu familier de la méthode function.apply en JavaScript. Je suppose que c'est pour exécuter la function navOver() en utilisant l'objet jQuery correspondant au a.active comme référence du mot-clé this dans le contexte de la fonction. Sauf que du coup this va correspondre à un objet jQuery, pas à un objet de type Element, et que donc ça revient à faire:
jQuery(jQueryObj).css().find('span').show();
ce qui ne devrait rien donner...

Une solution consisterait à faire:
navOver.apply( $("#topnav .active").parents("li").get(0) );

Mais ça reste un peu tiré par les cheveux cette histoire.

Si la structure de ton menu est relativement simple, le mieux serait d'avoir une classe "active" (ou "current", qui a ma préférence pour éviter la confusion avec la pseudo-classe CSS :active) non pas sur un élément A, mais sur le LI parent ou ancêtre. Tu peux alors faire:
$(document).ready(function() { 
  $("#topnav li:not(.current)").hover(
    function () {
      $(this).addClass('hover');
    }, 
    function () {
      $(this).removeClass('hover');
    }
  );
});

Ou ne même pas s'en préoccuper, et juste exploiter CSS et la priorité des sélecteurs correctement pour éviter qu'une classe .hover sur un LI ne prenne le pas sur une classe .current, par exemple.
Modifié par Florent V. (16 Aug 2009 - 20:32)
Merci beaucoup pour ta réponse.
Effectivement je pense que je n'étais pas parti sur le bon chemin...

J'ai suivi tes conseils et adapté légèrement le code et du coup ça marche Smiley biggrin