Komplexer CSS-Selektor für das übergeordnete Element des aktiven untergeordneten Elements [Duplikat]

StackOverflow https://stackoverflow.com/questions/45004

  •  09-06-2019
  •  | 
  •  

Frage

Auf diese Frage gibt es hier bereits eine Antwort:

Gibt es eine Möglichkeit, ein übergeordnetes Element basierend auf der Klasse eines untergeordneten Elements in der Klasse auszuwählen?Das für mich relevante Beispiel betrifft die HTML-Ausgabe durch ein schönes Menü-Plugin für http://drupal.org.Die Ausgabe wird wie folgt gerendert:

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

Meine Frage ist, ob es möglich ist, einen Stil auf das Listenelement anzuwenden, das den Anker mit der aktiven Klasse darauf enthält.Natürlich würde ich es vorziehen, wenn das Listenelement als aktiv markiert wäre, aber ich habe keine Kontrolle über den Code, der erzeugt wird.Ich könnte so etwas mit Javascript ausführen (da kommt mir JQuery in den Sinn), aber ich habe mich gefragt, ob es eine Möglichkeit gibt, dies mithilfe von CSS-Selektoren zu tun.

Um es klarzustellen: Ich möchte einen Stil auf das Listenelement anwenden, nicht auf den Anker.

War es hilfreich?

Lösung

Leider ist das mit CSS nicht möglich.

Mit JavaScript ist es jedoch nicht sehr schwierig:

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

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

Andere Tipps

Laut Wikipedia:

Selektoren können nicht aufsteigen

CSS bietet keine Möglichkeit, ein übergeordnetes Element oder einen Vorfahren eines Elements auszuwählen, das bestimmte Kriterien erfüllt.Ein erweitertes Auswahlschema (z. B. XPath) würde anspruchsvollere Stylesheets ermöglichen.Die Hauptgründe dafür, dass die CSS-Arbeitsgruppe Vorschläge für übergeordnete Selektoren ablehnt, hängen jedoch mit der Browserleistung und Problemen beim inkrementellen Rendering zusammen.

Und für alle, die in Zukunft nach SO suchen, könnte dies auch als Vorfahrenselektor bezeichnet werden.

Aktualisieren:

Der Selektoren Level 4 Spec Hier können Sie auswählen, welcher Teil der Auswahl der Betreff ist:

Das Thema des Selektors kann ausdrücklich identifiziert werden, indem ein Dollar -Zeichen ($) an einen der Verbindungsauswahler in einem Selektor vorbereitet wird.Obwohl die Elementstruktur, die der Selektor darstellt, mit oder ohne das Dollar -Vorzeichen gleich ist, kann das Angeben des Subjekts auf diese Weise ändern, welcher zusammengesetzte Selektor das Subjekt in dieser Struktur darstellt.

Beispiel 1:

Beispielsweise stellt der folgende Selektor ein Listenelement dar, das ein einzigartiges Kind einer geordneten Liste OL:

OL > LI:only-child

Das folgende stellt jedoch eine geordnete Liste aus, die ein einzigartiges Kind hat, wobei das Kind ein Li ist:

$OL > LI:only-child

Die von diesen beiden Selektoren dargestellten Strukturen sind gleich, die Probanden der Selektoren nicht.

Dies ist jedoch (derzeit November 2011) in keinem Browser oder als Selektor in jQuery verfügbar.

Wieder zu spät zur Party, aber für das, was es wert ist, ist es möglich, jQuery zu verwenden, um es etwas prägnanter zu machen.In meinem Fall musste ich das finden <ul> übergeordnetes Tag für a <span> Tag, der im Kind enthalten ist <li>.jQuery hat das :has Selektor, damit es möglich ist, ein übergeordnetes Element anhand der darin enthaltenen untergeordneten Elemente zu identifizieren (aktualisiert gemäß Kommentarreferenz von @Afrowave: https://api.jquery.com/has-selector/):

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

wird das auswählen ul Element, das ein untergeordnetes Element mit der ID hat someId.Oder um die ursprüngliche Frage zu beantworten, sollte etwa Folgendes ausreichen (ungetestet):

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

Der „Eltern“-Auswahlschalter

Derzeit gibt es in CSS (nicht einmal in CSS3) keine Option zum Auswählen des übergeordneten Elements eines Elements.Aber mit CSS4, Die wichtigste Neuigkeit im aktuellen W3C-Entwurf ist die Unterstützung des Elternselektors.

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

Wenn Sie mit der Maus über ein Listenelement fahren, wird die gesamte ungeordnete Liste hervorgehoben, indem ein weißer Hintergrund hinzugefügt wird.

Offizielle Dokumentation: https://www.w3.org/TR/2011/WD-selectors4-20110929/#overview (letzte Reihe).

Der erste Entwurf von Selektoren Ebene 4 beschreibt eine Möglichkeit, das explizit festzulegen Thema eines Selektors.Dies würde es dem OP ermöglichen, das Listenelement mit dem Selektor zu formatieren $li > a.active

Aus Bestimmen des Betreffs eines Selektors:

Der folgende Selektor stellt beispielsweise ein Listenelement LI dar, das einer geordneten Liste OL eindeutig untergeordnet ist:

OL > LI:only-child

Das Folgende stellt jedoch eine geordnete Liste OL mit einem eindeutigen Kind dar, wobei dieses Kind ein LI ist:

$OL > LI:only-child

Die von diesen beiden Selektoren dargestellten Strukturen sind dieselben, die Subjekte der Selektoren jedoch nicht.

Bearbeiten:Wenn man bedenkt, wie „entwickelt“ ein Spezifikationsentwurf sein kann, ist es am besten, dies im Auge zu behalten, indem man die überprüft CSSWGs Seite zu Selektoren Ebene 4.

Zukünftige Antwort mit CSS4-Selektoren

Neue CSS-Spezifikationen enthalten ein Experiment :has Pseudo-Selektor, der dies möglicherweise tun kann.

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

Der Browserunterstützung Diesbezüglich gibt es zum jetzigen Zeitpunkt im Grunde noch nichts, es wird aber darüber nachgedacht offizielle Spezifikationen.


Antwort im Jahr 2012, die im Jahr 2012 falsch war und im Jahr 2018 noch falscher ist

Es stimmt zwar, dass CSS nicht aufsteigen kann, aber es ist falsch, dass Sie das übergeordnete Element eines anderen Elements nicht abrufen können.Lassen Sie mich noch einmal wiederholen:

Mithilfe Ihres HTML-Beispielcodes können Sie das li abrufen, ohne li anzugeben

ul * a {
    property:value;
}

In diesem Beispiel ist ul das übergeordnete Element eines Elements und dieses Element ist das übergeordnete Element des Ankers.Der Nachteil dieser Methode besteht darin, dass, wenn eine ul mit einem untergeordneten Element vorhanden ist, das einen Anker enthält, diese die angegebenen Stile erbt.

Sie können auch den untergeordneten Selektor verwenden, da Sie ohnehin das übergeordnete Element angeben müssen.

ul>li a {
    property:value;
}

In diesem Beispiel muss der Anker ein Nachkomme eines li sein, das ein untergeordnetes Element von ul sein MUSS, was bedeutet, dass er sich innerhalb des Baums befinden muss, der auf die ul-Deklaration folgt.Dies wird etwas spezifischer sein und nur ein Listenelement erfassen, das einen Anker enthält UND ein untergeordnetes Element von ul ist.

Also, um Ihre Frage per Code zu beantworten.

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

Dies sollte die ul mit der Klasse „menu“ und das untergeordnete Listenelement, das nur einen Anker enthält, mit der Klasse „aktiv“ erfassen.

Ich hatte das gleiche Problem mit Drupal.Angesichts der Einschränkungen von CSS besteht die Möglichkeit, dies zum Laufen zu bringen, darin, die „aktive“ Klasse zu den übergeordneten Elementen hinzuzufügen, wenn der Menü-HTML generiert wird.Eine gute Diskussion darüber gibt es unter http://drupal.org/node/219804, Das Ergebnis ist, dass diese Funktionalität in Version 6.x-2.x des nicemenus-Moduls integriert wurde.Da sich dies noch in der Entwicklung befindet, habe ich den Patch auf 6.x-1.3 zurückportiert http://drupal.org/node/465738 damit ich die produktionsreife Version des Moduls weiterhin nutzen kann.

Viele Leute antworteten mit jQuery parent, aber nur um das zu ergänzen, wollte ich einen kurzen Codeausschnitt teilen, den ich zum Hinzufügen von Klassen zu meinen Navigationsgeräten verwende, damit ich ihnen Stile hinzufügen kann liDas hat nur Untermenüs und nicht liDas ist nicht der Fall.

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

Ich bin tatsächlich auf das gleiche Problem gestoßen wie beim Originalposter.Es gibt eine einfache Lösung: einfach verwenden .parent() jQuery-Selektor.Mein Problem war, dass ich es benutzte .parent anstatt .parent().Dummer Fehler, ich weiß.

Binden Sie die Ereignisse (in diesem Fall musste ich sie mit binden, da meine Registerkarten modal sind). .live anstelle eines 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;
})

Hier ist der HTML-Code.

<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>

Natürlich können Sie dieses Muster wiederholen ... mit mehr LIs

Mir ist gerade noch ein anderer Gedanke gekommen, der eine reine CSS-Lösung sein könnte.Zeigen Sie Ihre aktive Klasse als absolut positionierten Block an und legen Sie ihren Stil so fest, dass er die übergeordnete Klasse verdeckt.

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;
}    

Für diejenigen unter Ihnen, die Javascript ohne JQuery verwenden möchten ...

Die Auswahl des übergeordneten Elements ist trivial.Du brauchst ein getElementsByClass Funktion irgendeiner Art, es sei denn, Sie können Ihr Drupal-Plugin dazu bringen, dem aktiven Element eine ID anstelle einer Klasse zuzuweisen.Die Funktion, die ich bereitgestellt habe, habe ich von einem anderen Genie auf SO übernommen.Es funktioniert gut. Bedenken Sie beim Debuggen jedoch, dass die Funktion immer ein Array von Knoten zurückgibt, nicht nur einen einzelnen Knoten.

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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top