2010-01-12 5 views
12

Quindi, ho una navigazione che è una lista e ha sottoliste e sottoliste.Spostare più genitori in jQuery - modo più efficiente?

Fondamentalmente, il nav è per impostazione predefinita compresso, ma se le persone fanno clic su una pagina che si trova in una sottolista, voglio mostrare l'elenco dei genitori. E se è una sottolista di una sottolista, ho bisogno di entrambe le liste dei genitori da mostrare. L'ho impostato, ma non mi piace mettere 5 .parent(). Parent() per attraversare verso l'alto per espandere la lista. C'è un modo più efficiente?

il codice HTML:

<div id="lesson-sidebar"> 
     <ul> 
      <li><a href="index.html">Welcome to Beat Basics and Beyond</a></li> 
      <li><a href="table-of-contents.html">What's in this course?</a></li> 
      <li><a href="defining-your-beat.html" class="active">Defining Your Beat</a> 
       <ul> 
        <li><a href="boundaries-of-your-beat.html">Boundaries of Your Beat</a></li> 
        <li><a href="the-beat-description.html">The Beat Description</a></li> 
        <li><a href="build-your-own-beat-description.html"><span class="ital">Activity:</span> Build Your Own Beat Description</a></li> 
       </ul> 
      </li> 
      <li><a href="getting-started.html">Getting Started</a> 
       <ul> 
        <li><a href="debrief-your-predecessor.html">Debrief Your Predecessor</a></li> 
        <li><a href="predecessor-top-five-tips.html"><span class="ital">Activity:</span> List The Top Five Tips From Your Predecessor</a></li> 
        <li><a href="covering-your-beat-with-the-internet.html">Covering Your Beat With The Internet</a></li> 
        <li><a href="get-in-the-car-and-go.html">Get in the Car and Go</a></li> 
        <li><a href="mapping-your-beat.html">Mapping Your Beat</a></li> 
        <li><a href="read-the-clips.html">Read the Clips</a></li> 
        <li><a href="activity-dissect-this-clip.html"><span class="ital">Activity:</span> Dissect This Clip</a></li> 
        <li><a href="writing-your-first-article.html">Writing Your First Article</a></li> 
        <li><a href="starting-cold-on-the-beat.html">Starting Cold on the Beat</a></li> 
       </ul>   
      </li> 
      <li><a href="working-with-sources.html">Working With Sources</a> 
       <ul> 
        <li><a href="finding-sources.html">Finding Sources</a></li> 
        <li><a href="diversify-your-sources.html">Diversify Your Sources</a></li> 
        <li><a href="prospecting-for-stories-and-sources.html">Prospecting for Stories and Sources</a></li> 
        <li><a href="building-relationships.html">Building Relationships</a></li> 
        <li><a href="going-off-the-record.html">Going Off the Record</a></li> 
       </ul> 
      </li> 
      <li><a href="developing-resources.html">Developing Resources to Help You on the Beat</a> 
       <ul> 
        <li><a href="develop-a-calendar-of-events.html">Develop a Calendar of Events</a></li> 
        <li><a href="build-your-library.html">Build Your Library</a></li> 
        <li><a href="learn-the-open-record-laws.html">Learn the Open Record Laws</a></li> 
       </ul> 
      </li> 
      <li><a href="extra-resources.html">Extra Resources</a> 
       <ul> 
        <li><a href="beat-breakdown-tool.html">Beat Breakdown Tool</a></li> 
        <li><a href="links-library.html">Links Library</a> 
         <ul> 
          <li><a href="general-resources-for-any-beat.html">General Resources for Any Beat</a></li> 
          <li><a href="courts-and-criminal-justice-links.html">Courts and Criminal Justice Links</a></li> 
          <li><a href="education-resources.html">Education Resources</a></li> 
          <li><a href="local-government-links.html">Local Government Links</a></li> 
          <li><a href="neighborhood-or-suburban-links.html">Neighborhood or Suburban Links</a></li> 
          <li><a href="police-and-public-safety-links.html">Police and Public Safety Links</a></li> 
          <li><a href="reporter-organizations.html">Reporter Organizations</a></li> 
         </ul> 
        </li> 
        <li><a href="additional-reading.html">Additional Reading</a></li> 
       </ul> 
      </li> 
      <li><a href="final-thoughts.html">Final Thoughts</a></li> 
     </ul> 

Il jQuery:

function toggleSubmenu() { 

    if ($(this).hasClass('submenu-hidden')) { 

     $(this).parent().children('ul').slideToggle(); 
     $(this).removeClass().addClass('submenu-visible'); 

    } else if ($(this).hasClass('submenu-visible')) { 

     $(this).parent().children('ul').slideToggle(); 
     $(this).removeClass().addClass('submenu-hidden'); 
    } 
} 

$('#lesson-sidebar ul ul').hide(); 
$('#lesson-sidebar ul ul ul').hide(); 
$('#lesson-sidebar ul:first-child').attr('id', 'rootlist'); 
$('#lesson-sidebar ul li:has("ul")').prepend('<span class="submenu-hidden"></span>').css('list-style','none'); 

$('#lesson-sidebar ul li a').each(
    function() { 
     if ($(this).hasClass('active')) { 
      // if it is a UL 
      var length = $(this).parent().find("ul").length; 
      alert(length); 
      if (length == 0) { 
       if ($(this).parent().parent().parent().children('span').hasClass('submenu-hidden')) { 
         $(this).parent().parent().parent().children('ul').show(); 
         $(this).parent().parent().parent().children('span').removeClass('submenu-hidden').addClass('submenu-visible'); 
       } 
       if ($(this).parent().parent().parent().parent().parent().children('span').hasClass('submenu-hidden')) { 
         $(this).parent().parent().parent().parent().parent().children('ul').show(); 
         $(this).parent().parent().parent().parent().parent().children('span').removeClass('submenu-hidden').addClass('submenu-visible'); 
       } 
      } 
      if (length == 1) { 
       $(this).parent().find('ul').slideToggle(); 
       $(this).parent().children('span').removeClass('submenu-hidden').addClass('submenu-visible'); 
      }    
     } 
    } 
); 

$('ul#rootlist > li span, ul#rootlist li ul li > span').bind('click', toggleSubmenu); 

ne e tutto l'aiuto è apprezzato majorly.

risposta

12

Se ho capito quello che stai cercando di fare ... si può fare qualcosa di simile:

// For my benefit, hide all lists except the root items 
$('ul, li', $('#lesson-sidebar ul li')).hide(); 

// Show active parents and their siblings 
$('li a.active').parents('ul, li').each(function() { 
    $(this).siblings().andSelf().show(); 
}); 

// Show the active item and its siblings 
$('li a.active').siblings().andSelf().show(); 

I parents() e siblings() metodi sono entrambi grandi per questo genere di cose.

Modifica: prima c'era un errore che non mostrava i fratelli genitore. Prova questa nuova versione.

Edit 2: Ora funziona con class = "active" sull'ancora anziché sull'elemento dell'elenco.

+0

Questo è più o meno quello che sto cercando. La cosa dei genitori è incredibile !! Avevo trovato una soluzione usando il metodo: eq, ma questo è molto più pulito. L'unica cosa è che non è li.attivo, è un.attivo, e quindi sto ancora cercando di far mostrare i fratelli. Grazie mille: D –

+0

L'ho appena modificato per funzionare con a.active. Per favore ricorda di votare e colpire il segno di spunta verde accanto alla risposta se funziona. :) –

+0

Controllato e votato. La tua risposta veloce e chiara è stata di grande aiuto. –

16

$(this).closest("ul") attraverseranno i genitori finché non trova un ul

http://docs.jquery.com/Traversing/closest#expr

... ottenere il primo elemento che corrisponde al selettore di testando l'elemento stesso e l'attraversamento attraverso i suoi antenati nel DOM albero ...

0

$(this).parents().get()[4] vi darà la quinta

3

Per semplificare risposta molto utile di Lance McNeary, il trucco è quello di utilizzare:

.parents([selector]) 

Dato un oggetto jQuery che rappresenta un insieme di elementi DOM, i .parents() metodo ci permette di cercare attraverso gli antenati di questi elementi nell'albero DOM e costruire un nuovo oggetto jQuery dagli elementi di corrispondenza ordinati dal genitore immediato in su; gli elementi vengono restituiti in ordine dal genitore più vicino a quelli esterni.

Un altro utente ha suggerito:

.closest([selector]) 

Simile a .parents(), questo può essere una scelta migliore come si ferma una volta che trova l'elemento che sta cercando. Sembra che sarebbe più efficiente in questo caso. Vedere http://api.jquery.com/closest/ per ulteriori dettagli. Spero che questo aiuti le persone a capire le differenze tra .closest() e .parents() e quanto può essere jQuery potente e flessibile.

+0

Si prega di non riformulare altre risposte. Una nuova risposta è per portare una nuova idea. Si prega di commentare o suggerire modifiche se qualcosa deve essere migliorato. –

+1

Penso che la risposta di Michael sia più pulita. Mi ha aiutato quando non riuscivo a capire il punto della risposta di Lance. –

-1

Prova con questa linea di codice:

$(this).parent().parent().fadeOut(); 
+2

Aggiungi una spiegazione per la tua risposta. –