2010-02-22 2 views
1

J'ai une barre de navigation qui a deux listes déroulantes (comme ul's imbriqués). J'essaye de basculer les subnavs quand son parent est cliqué. Ou masquer une sous-navigation lorsque l'autre parent est cliqué. Voici le balisage:Est-ce la meilleure façon de faire cela?

<div id="nav-bar"> 
    <a href="#">A link</a> | 
    <ul> 
    <li id="feedback"> 
     <a href="javascript:void(0);">Feedback</a> 
     <ul class="subnav"> 
     <li><a href="#">Give us feedback</a></li> 
     </ul> 
    </li> 
    </ul> | 
    <a href="#">Another link</a> | 
    <ul> 
    <li id="location"> 
     <a href="javascript:void(0);">Pick your location</a> 
     <ul class="subnav"> 
     <li><a href="#">Los Angeles</a></li> 
     <li><a href="#">New York</a></li> 
     </ul> 
    </li> 
    </ul> 
</div> 

Et le code:

//hide the subnavs and give them a little down arrow 
$('ul.subnav').hide().parent().append('<small>&#9660;</small>'); 

// show its subnav when clicked 
$('#nav-bar ul li').click(function() { 
    var subnav = $(this).children('ul.subnav'); 
    // hide the other's subnav if it's visible 
    if ($(this).attr('id') == 'location') { 
    subnav.toggle(); 
    $('li#feedback').children('ul.subnav').hide(); 
    } else { 
    subnav.toggle(); 
    $('li#location').children('ul.subnav').hide(); 
    } 
}); 

Encore un novice à JS et jQuery, je voudrais savoir s'il y a une façon moins détaillée pour accomplir ce que je suis en train de faire ci-dessus. Edit: Une meilleure question est, est-il un moyen de le faire sans avoir à donner explicitement le li's un ID?

+1

Vous devriez dire ce que vous essayez d'atteindre .. plutôt que de laisser les gens essayer de le comprendre à partir de votre code .. comment savons-nous ce que vous essayez de faire est ce que votre code est? – Layke

+0

J'essaie de basculer les sous-contacts lorsque l'on clique sur son parent. Ou masquer une sous-navigation lorsque l'autre parent est cliqué. – farkenfooken

+0

Heed Laykes. Vous devez fournir une explication de ce que vous essayez de faire et, en particulier, de ce que vous n'aimez pas dans la façon dont vous le faites actuellement. –

Répondre

1

Un meilleur format serait quelque chose comme ceci pour votre HTML:

<ul id="nav-bar"> 
    <li><a href="#">A link</a> |</li> 
    <li> 
    <a href="#">Feedback</a> | 
    <ul class="subnav"> 
     <li><a href="#">Give us feedback</a></li> 
    </ul> 
    </li> 
    <li><a href="#">Another link</a> |</li> 
    <li> 
    <a href="#">Pick your location</a> | 
    <ul class="subnav"> 
     <li><a href="#">Los Angeles</a></li> 
     <li><a href="#">New York</a></li> 
    </ul> 
    </li> 
</ul> 

Alors votre code jQuery ressemblerait à ceci:

$(function(){ 
    var $nav = $("#nav-bar"), 
     $subnav = $nav.find("ul.subnav").hide(); 

    $nav.children('li:has(ul.subnav)').click(function(e){ 
    e.preventDefault(); 
    var $sub = $(this).children('ul.subnav').toggle(); 
    $subnav.not($sub).hide(); 
    }) 
}) 
+0

C'est plus comme ça que j'aimerais l'avoir fait. Fonctionne très bien. Je sais que cela vous demande beaucoup d'explications, mais quelle était votre rime ou raison de le faire de cette façon? Et la façon dont je l'ai fait n'est-elle pas idéale et pourquoi? – farkenfooken

+0

@farkenfooken D'abord, j'ai essayé d'utiliser le balisage sémantique (qui a entraîné moins de balisage) en décrivant la navigation comme une «liste de liens» avec certains liens ayant des «sous-listes». Puis, sur le jQuery, en mettant en cache les ensembles de résultats dans les variables, j'ai accéléré les temps de recherche (jQuery n'a pas besoin de retrouver le même élément encore et encore). Et enfin, j'ai utilisé des sélecteurs jQuery plus complexes au lieu de noms de classes ou d'id pour garder le balisage aussi simple que possible. Il pourrait être simplifié davantage si nécessaire. –

+0

Merci d'avoir pris le temps de répondre à mes questions. – farkenfooken

0

Eh bien, il y a quelques façons que vous pouvez faire C'est un peu plus facile de maintenir votre code. Voici un exemple rapide:

//hide the subnavs and give them a little down arrow 
$('ul.subnav').hide().parent().append('<small>&#9660;</small>'); 

// show its subnav when clicked 
$('#nav-bar ul li').click(function() { 
    var subnav = $(this).children('ul.subnav'); 
    // hide the other's subnav if it's visible 

$('ul.subnav').hide(); 
subnav.toggle(); 
}); 

Fondamentalement, cela Remasquez à nouveau tous les éléments les « subnav », puis montrer celui qui a été cliqué. Mais la principale différence ici est que vous pouvez maintenant ajouter un troisième, quatrième, menu déroulant, etc., ou changer les ID sans avoir à changer le javascript.

Le code HTML que vous utilisez est plutôt bon et relativement similaire aux menus de navigation «standard».

Edit: Ce qui est apparemment similaire à la réponse précédente: P

+0

Cela l'a fait pour moi avec le moins de changement de code. – farkenfooken

+0

Je devrais noter ceci ne bascule pas avec succès le li que vous cliquez, montre seulement lui. – farkenfooken

0

je me débarrasser du code en ligne javascript:void(0) il est unecessary. Avoir votre lien lien vers "#".

Vous ne voulez certainement pas faire correspondre les ID comme ça, ça ne fonctionne pas très bien. Au lieu de cela, quelque chose comme cela devrait fonctionner (non testé):

$('#nav-bar ul li').click(function() {  
    $(this) 
    //hide all subnavs 
    .closest("#nav-bar").find("ul.subnav").hide().end().end() 
    //show subnav under the li clicked 
    .find("ul.subnav").show();  
}); 

Chaque fois que possible, vous voulez le code chain your jquery afin que vous n'avez pas à saisir un nouvel élément à chaque fois, du Royaume. D'après ce que je comprends, il est plus efficace de chaîner car il traverse l'élément déjà trouvé, plutôt que d'aller chercher un nouveau. Le .end() rétablit votre chaîne à l'élément trouvé précédent, donc quand je dis .closest ("blah"). Find ("blah2") je vais deux niveaux de profondeur. .end(). end() me ramènera à l'élément d'origine (this) afin que je puisse trouver le subnav spécifique en dessous.

+0

Merci, je n'avais aucune idée de .end() jusqu'à maintenant. – farkenfooken

Questions connexes