Domanda

Questa domanda ha già una risposta qui:

C'è un modo per selezionare un elemento genitore in base alla classe di un elemento figlio nella classe?L'esempio che mi interessa riguarda l'output HTML di un simpatico plugin di menu per http://drupal.org.L'output viene visualizzato in questo modo:

<ul class="menu">  
    <li>  
        <a class="active">Active Page</a>  
    </li>  
    <li>    
        <a>Some Other Page</a>  
    </li>  
</ul>  

La mia domanda è se sia possibile applicare o meno uno stile all'elemento dell'elenco che contiene l'ancora con la classe attiva su di esso.Ovviamente preferirei che l'elemento dell'elenco fosse contrassegnato come attivo, ma non ho il controllo del codice che viene prodotto.Potrei eseguire questo genere di cose utilizzando JavaScript (mi viene in mente JQuery), ma mi chiedevo se esiste un modo per farlo utilizzando i selettori CSS.

Giusto per essere chiari, voglio applicare uno stile all'elemento dell'elenco, non all'ancora.

È stato utile?

Soluzione

Sfortunatamente, non c'è modo di farlo con i CSS.

Non è molto difficile con JavaScript però:

// JavaScript code:
document.getElementsByClassName("active")[0].parentNode;

// jQuery code:
$('.active').parent().get(0); // This would be the <a>'s parent <li>.

Altri suggerimenti

Secondo Wikipedia:

I selettori non sono in grado di salire

I CSS non offrono alcun modo per selezionare un genitore o un antenato di un elemento che soddisfi determinati criteri.Uno schema di selezione più avanzato (come XPath) consentirebbe fogli di stile più sofisticati.Tuttavia, le ragioni principali per cui il gruppo di lavoro CSS rifiuta le proposte di selettori principali sono legate alle prestazioni del browser e ai problemi di rendering incrementale.

E per chiunque cerchi SO in futuro, questo potrebbe anche essere definito un selettore di antenati.

Aggiornamento:

IL Selettori Livello 4 Spec ti permette di selezionare quale parte della selezione è l'oggetto:

L'oggetto del selettore può essere esplicitamente identificato preparando un segno di dollaro ($) a uno dei selettori composti in un selettore.Sebbene la struttura dell'elemento che il selettore rappresenta sia la stessa con o senza il segno del dollaro, indicando che il soggetto in questo modo può cambiare quale selettore composto rappresenta il soggetto in quella struttura.

Esempio 1:

Ad esempio, il seguente selettore rappresenta un elenco elemento li figlio univoco di un elenco ordinato ol:

OL > LI:only-child

Tuttavia, il seguente rappresenta un elenco ordinato con un bambino unico, quel bambino è un li:

$OL > LI:only-child

Le strutture rappresentate da questi due selettori sono uguali, ma i soggetti dei selettori non lo sono.

Sebbene questo non sia disponibile (attualmente, novembre 2011) in nessun browser o come selettore in jQuery.

Di nuovo tardi alla festa, ma per quello che vale è possibile usare jQuery per essere un po' più concisi.Nel mio caso avevo bisogno di trovare il file <ul> tag genitore per a <span> tag contenuto nel bambino <li>.jQuery ha il :has selettore in modo che sia possibile identificare un genitore dai figli che contiene (aggiornato in base al commento di @Afrowave rif: https://api.jquery.com/has-selector/):

$("ul").has("#someId")

selezionerà il ul elemento che ha un elemento figlio con id alcuniId.Oppure, per rispondere alla domanda originale, qualcosa di simile dovrebbe fare al caso tuo (non testato):

$("li").has(".active")

IL SELETTORE “GENITORE”.

Al momento, non esiste alcuna opzione per selezionare il genitore di un elemento nei CSS (nemmeno CSS3).Ma con CSS4, la novità più importante nell'attuale bozza del W3C è il supporto per il parent selector.

$ul li:hover{
    background: #fff;
}

Utilizzando quanto sopra, quando si passa con il mouse su un elemento dell'elenco, l'intero elenco non ordinato verrà evidenziato aggiungendovi uno sfondo bianco.

Documentazione ufficiale: https://www.w3.org/TR/2011/WD-selectors4-20110929/#overview (ultima riga).

La prima bozza di Selettori Livello 4 delinea un modo per impostare esplicitamente il soggetto di un selezionatore.Ciò consentirebbe all'OP di definire lo stile dell'elemento dell'elenco con il selettore $li > a.active

Da Determinazione dell'oggetto di un selettore:

Ad esempio, il seguente selettore rappresenta un elemento di elenco LI figlio univoco di un elenco ordinato OL:

OL > LI:only-child

Tuttavia quello seguente rappresenta una lista ordinata OL avente un figlio unico, che è un LI:

$OL > LI:only-child

Le strutture rappresentate da questi due selettori sono le stesse, ma i soggetti dei selettori non lo sono.

Modificare:Dato quanto "bozza" può essere una bozza di specifica, è meglio tenerla sotto controllo controllando il file La pagina di CSSWG sui selettori di livello 4.

Risposta futura con i selettori CSS4

Le nuove specifiche CSS contengono un file sperimentale :has pseudo selezionatore che potrebbe essere in grado di fare questa cosa.

li:has(a:active) {
  /* ... */
}

IL supporto del browser su questo è praticamente inesistente in questo momento, ma è in considerazione sul specifiche ufficiali.


Risposta nel 2012 che era sbagliata nel 2012 ed è ancora più sbagliata nel 2018

Sebbene sia vero che i CSS non possono ASCEND, non è corretto che non sia possibile acquisire l'elemento genitore di un altro elemento.Vorrei ribadire:

Utilizzando il codice di esempio HTML, puoi acquisire li senza specificare li

ul * a {
    property:value;
}

In questo esempio, ul è il genitore di qualche elemento e quell'elemento è il genitore di ancoraggio.Lo svantaggio dell'utilizzo di questo metodo è che se è presente un ul con un elemento figlio che contiene un'ancora, eredita gli stili specificati.

Puoi anche utilizzare il selettore figlio poiché dovrai comunque specificare l'elemento genitore.

ul>li a {
    property:value;
}

In questo esempio, l'ancora deve essere un discendente di un li che DEVE essere figlio di ul, ovvero deve trovarsi all'interno dell'albero successivo alla dichiarazione ul.Questo sarà un po' più specifico e prenderà solo un elemento dell'elenco che contiene un'ancora ED è un figlio di ul.

Quindi, per rispondere alla tua domanda tramite codice.

ul.menu > li a.active {
    property:value;
}

Questo dovrebbe catturare ul con la classe di menu e l'elemento dell'elenco figlio che contiene solo un'ancora con la classe di active.

Ho avuto lo stesso problema con Drupal.Date le limitazioni dei CSS, il modo per farlo funzionare è aggiungere la classe "attiva" agli elementi principali quando viene generato il menu HTML.C'è una bella discussione su questo su http://drupal.org/node/219804, il risultato è che questa funzionalità è stata implementata nella versione 6.x-2.x del modulo nicemenus.Dato che è ancora in fase di sviluppo, ho effettuato il backport della patch alla versione 6.x-1.3 at http://drupal.org/node/465738 in modo da poter continuare a utilizzare la versione pronta per la produzione del modulo.

Molte persone hanno risposto con jQuery genitore, ma solo per aggiungere qualcosa, volevo condividere un breve frammento di codice che utilizzo per aggiungere classi ai miei navigatori in modo da poter aggiungere uno stile a liHa solo sottomenu e non liè così, non farlo.

$("li ul").parent().addClass('has-sub');

In realtà ho riscontrato lo stesso problema del poster originale.C'è una soluzione semplice: basta usare .parent() Selettore jQuery.Il mio problema era che stavo usando .parent invece di .parent().Stupido errore, lo so.

Associa gli eventi (in questo caso poiché le mie schede sono in Modal dovevo unirli con .live invece di un basic .click.

$('#testTab1 .tabLink').live('click', function() {
    $('#modal ul.tabs li').removeClass("current"); //Remove any "current" class
    $(this).parent().addClass("current"); //Add "current" class to selected tab
    $('#modal div#testTab1 .tabContent').hide();
    $(this).next('.tabContent').fadeIn();   
    return false;
})
$('#testTab2 .tabLink').live('click', function() {
    $('#modal ul.tabs li').removeClass("current"); //Remove any "current" class
    $(this).parent().addClass("current"); //Add "current" class to selected tab
    $('#modal div#testTab2 .tabContent').hide();
    $(this).next('.tabContent').fadeIn();   
    return false;
})

Ecco l'HTML..

<div id="tabView1" style="display:none;">
  <!-- start: the code for tabView 1 -->
  <div id="testTab1" style="width:1080px; height:640px; position:relative;">
    <h1 class="Bold_Gray_45px">Modal Header</h1>
    <div class="tabBleed"></div>
    <ul class="tabs">
      <li class="current"> <a href="#" class="tabLink" id="link1">Tab Title Link</a>
        <div class="tabContent" id="tabContent1-1">
          <div class="modalCol">
            <p>Your Tab Content</p>
            <p><a href="#" class="tabShopLink">tabBased Anchor Link</a> </p>
          </div>
          <div class="tabsImg"> </div>
        </div>
      </li>
      <li> <a href="#" class="tabLink" id="link2">Tab Title Link</a>
        <div class="tabContent" id="tabContent1-2">
          <div class="modalCol">
            <p>Your Tab Content</p>
            <p><a href="#" class="tabShopLink">tabBased Anchor Link</a> </p>
          </div>
          <div class="tabsImg"> </div>
        </div>
      </li>
    </ul>
  </div>
</div>

Naturalmente puoi ripetere lo schema... con più LI

Proprio adesso mi è venuto in mente un altro pensiero che potrebbe essere una soluzione CSS pura.Visualizza la tua classe attiva come un blocco posizionato in modo assoluto e imposta il suo stile per coprire il genitore li.

a.active {
   position:absolute;
   display:block;
   width:100%;
   height:100%;
   top:0em;
   left:0em;
   background-color: whatever;
   border: whatever;
}
/* will also need to make sure the parent li is a positioned element so... */
ul.menu li {
    position:relative;
}    

Per quelli di voi che vogliono usare Javascript senza jquery...

Selezionare il genitore è banale.Avete bisogno di un getElementsByClass funzione di qualche tipo, a meno che tu non riesca a fare in modo che il tuo plugin drupal assegni all'elemento attivo un ID invece di Class.La funzione che ho fornito l'ho presa da qualche altro genio su SO.Funziona bene, tieni presente durante il debug che la funzione restituirà sempre un array di nodi, non solo un singolo nodo.

active_li = getElementsByClass("active","a");
active_li[0].parentNode.style.whatever="whatever";

function getElementsByClass(node,searchClass,tag) {
    var classElements = new Array();
    var els = node.getElementsByTagName(tag); // use "*" for all elements
    var elsLen = els.length;
    var pattern = new RegExp("\\b"+searchClass+"\\b");
    for (i = 0, j = 0; i < elsLen; i++) {
       if ( pattern.test(els[i].className) ) {
       classElements[j] = els[i];
       j++;
   }
}
return classElements;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top