1155 Stimmen

Auswahl und Manipulation von CSS-Pseudoelementen wie ::before und ::after unter Verwendung von javascript (oder jQuery)

Gibt es eine Möglichkeit zur Auswahl/Manipulation von CSS-Pseudo-Elementen wie ::before y ::after (und die alte Version mit einem Semikolon) mit jQuery?

Mein Stylesheet hat zum Beispiel die folgende Regel:

.span::after{ content:'foo' }

Wie kann ich "foo" in "bar" mit Vanilla JS oder jQuery ändern?

781voto

Nick Kline Punkte 7834

Sie könnten auch den Inhalt mit einem data-Attribut an das Pseudo-Element übergeben und dann jQuery verwenden, um diesen zu bearbeiten:

In HTML:

<span>foo</span>

In jQuery:

$('span').hover(function(){
    $(this).attr('data-content','bar');
});

In CSS:

span:after {
    content: attr(data-content) ' any other text you may want';
}

Wenn Sie verhindern wollen, dass der "andere Text" angezeigt wird, können Sie dies mit der Lösung von seucolega wie folgt kombinieren:

In HTML:

<span>foo</span>

In jQuery:

$('span').hover(function(){
    $(this).addClass('change').attr('data-content','bar');
});

In CSS:

span.change:after {
    content: attr(data-content) ' any other text you may want';
}

562voto

Blazemonger Punkte 85817

Man sollte meinen, dass diese Frage einfach zu beantworten ist, mit allem, was jQuery sonst noch so kann. Leider liegt das Problem in einer technischen Frage begründet: css :after und :before Regeln sind nicht Teil des DOM, und kann daher nicht mit den DOM-Methoden von jQuery geändert werden.

Dort sind Es gibt verschiedene Möglichkeiten, diese Elemente mit JavaScript und/oder CSS zu manipulieren; welche Sie verwenden, hängt von Ihren genauen Anforderungen ab.


Ich werde mit dem Ansatz beginnen, der allgemein als der "beste" angesehen wird:

1) Hinzufügen/Entfernen einer vorgegebenen Klasse

Bei diesem Ansatz haben Sie bereits eine Klasse in Ihrem CSS mit einem anderen :after o :before Stil. Platzieren Sie diese "neue" Klasse später in Ihrem Stylesheet, um sicherzustellen, dass sie überschrieben wird:

p:before {
    content: "foo";
}
p.special:before {
    content: "bar";
}

Dann können Sie diese Klasse mit jQuery (oder Vanilla JavaScript) leicht hinzufügen oder entfernen:

$('p').on('click', function() {
    $(this).toggleClass('special');
});

    $('p').on('click', function() {
      $(this).toggleClass('special');
    });

p:before {
  content: "foo";
  color: red;
  cursor: pointer;
}
p.special:before {
  content: "bar";
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
  • Vorteile: Einfach mit jQuery zu implementieren; ändert schnell mehrere Stile auf einmal; erzwingt die Trennung von Belangen (Isolierung Ihrer CSS und JS von Ihrem HTML)
  • Nachteile: CSS muss vorformuliert sein, so dass der Inhalt von :before o :after nicht vollständig dynamisch ist

2) Neue Stile direkt zum Stylesheet des Dokuments hinzufügen

Es ist möglich, JavaScript zu verwenden, um Stile direkt in das Stylesheet des Dokuments einzufügen, einschließlich :after y :before Stile. jQuery bietet keine bequeme Abkürzung, aber zum Glück ist das JS nicht so kompliziert:

var str = "bar";
document.styleSheets[0].addRule('p.special:before','content: "'+str+'";');

var str = "bar";
document.styleSheets[0].addRule('p.special:before', 'content: "' + str + '";');

p:before {
  content: "foo";
  color: red;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>

.addRule() und die damit verbundenen .insertRule() Methoden sind heute recht gut unterstützt.

Als Variante können Sie auch jQuery verwenden, um dem Dokument ein völlig neues Stylesheet hinzuzufügen, aber der dafür erforderliche Code ist nicht sauberer:

var str = "bar";
$('<style>p.special:before{content:"'+str+'"}</style>').appendTo('head');

var str = "bar";
$('<style>p.special:before{content:"' + str + '"}</style>').appendTo('head');

p:before {
  content: "foo";
  color: red;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>

Wenn es darum geht, die Werte zu "manipulieren" und nicht nur zu addieren, können wir auch lesen die bestehenden :after o :before Stile mit einem anderen Ansatz:

var str = window.getComputedStyle(document.querySelector('p'), ':before') 
           .getPropertyValue('content');

var str = window.getComputedStyle($('p')[0], ':before').getPropertyValue('content');
console.log(str);

document.styleSheets[0].addRule('p.special:before', 'content: "' + str+str + '";');

p:before {
    content:"foo";
    color: red;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>

Wir können ersetzen document.querySelector('p') con $('p')[0] bei der Verwendung von jQuery, für etwas kürzeren Code.

  • Vorteile: eine beliebige Zeichenfolge kann dynamisch in den Stil eingefügt werden
  • Nachteile: die ursprünglichen Stile werden nicht verändert, sondern nur überschrieben; wiederholte (missbräuchliche) Verwendung kann das DOM beliebig groß werden lassen

3) Ändern Sie ein anderes DOM-Attribut

Sie können auch zu verwenden. attr() in Ihrem CSS um ein bestimmtes DOM-Attribut zu lesen. ( Wenn ein Browser Folgendes unterstützt :before unterstützt es attr() auch. ) Durch die Kombination mit content: in einem sorgfältig vorbereiteten CSS, können wir den Inhalt ändern (aber nicht andere Eigenschaften, wie Rand oder Farbe) von :before y :after dynamisch:

p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}

JS:

$('p').on('click', function () {
    $(this).attr('data-before','bar');
});

$('p').on('click', function () {
    $(this).attr('data-before','bar');
});

p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p>This is a paragraph.</p>
<p>This is another paragraph.</p>

Dies kann mit der zweiten Technik kombiniert werden, wenn das CSS nicht im Voraus zubereitet werden kann:

var str = "bar";

document.styleSheets[0].addRule('p:before', 'content: attr(data-before);');

$('p').on('click', function () {
    $(this).attr('data-before', str);
});

var str = "bar";
document.styleSheets[0].addRule('p:before', 'content: attr(data-before) !important;');

$('p').on('click', function() {
  $(this).attr('data-before', str);
});

p:before {
  content: "foo";
  color: red;
  cursor: pointer;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
  • Vorteile: Erzeugt keine endlosen zusätzlichen Stile
  • Nachteile: attr in CSS kann nur für Inhaltsstrings gelten, nicht für URLs oder RGB-Farben

170voto

BoltClock Punkte 660640

Obwohl sie von den Browsern über CSS so dargestellt werden, als wären sie wie andere echte DOM-Elemente, sind Pseudo-Elemente selbst nicht Teil des DOM, da Pseudo-Elemente, wie der Name schon sagt, keine echten Elemente sind und man sie daher nicht direkt mit jQuery (oder 何れも JavaScript-APIs, ja nicht einmal die Selektoren-API ). Dies gilt für alle Pseudo-Elemente, deren Stile Sie mit einem Skript zu ändern versuchen, und nicht nur für ::before y ::after .

Sie können nur auf Pseudo-Elementstile direkt zur Laufzeit über die CSSOM zugreifen (denken Sie an window.getComputedStyle() ), die von jQuery nicht über .css() eine Methode, die auch keine Pseudo-Elemente unterstützt.

Man kann aber auch andere Wege finden, um das Problem zu umgehen, zum Beispiel:

  • Anwendung der Stile auf die Pseudo-Elemente einer oder mehrerer beliebiger Klassen, dann Umschalten zwischen den Klassen (siehe seucolega's Antwort für ein schnelles Beispiel) - dies ist der idiomatische Weg, da er einfache Selektoren verwendet (was Pseudoelemente nicht sind), um zwischen Elementen und Elementzuständen zu unterscheiden, so wie sie verwendet werden sollen

  • Manipulation der Stile, die auf die Pseudo-Elemente angewendet werden, durch Änderung des Stylesheets des Dokuments, was viel mehr ein Hack ist

98voto

Temani Afif Punkte 208075

Wir können uns auch auf benutzerdefinierte Eigenschaften (auch CSS-Variablen genannt) um das Pseudo-Element zu bearbeiten. Wir können in der Spezifikation das:

Benutzerdefinierte Eigenschaften sind gewöhnliche Eigenschaften, d.h. sie können für jedem Element deklariert werden, werden mit der normale Vererbung y Kaskade Regeln kann mit @media und anderen bedingten Regeln konditionalisiert werden, kann verwendet werden in Das HTML-Attribut style sein kann. lesen oder setzen mit dem CSSOM , usw.

Die Idee ist, die benutzerdefinierte Eigenschaft innerhalb des Elements zu definieren, und das Pseudoelement erbt sie einfach, so dass wir sie leicht ändern können.

1) Inline-Stil verwenden :

.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}

<div class="box"></div>
<div class="box" style="--color:blue;--content:'I am a blue element'"></div>
<div class="box" style="--color:black"></div>
<div class="box" style="--color:#f0f;--content:'another element'"></div>

2) Verwendung von CSS und Klassen

.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}

.blue {
  --color:blue;
  --content:'I am a blue element';
}
.black {
  --color:black;
}

<div class="box"></div>
<div class="box black" ></div>
<div class="box blue"></div>

3) Verwendung von Javascript

document.querySelectorAll('.box')[0].style.setProperty("--color", "blue");
document.querySelectorAll('.box')[1].style.setProperty("--content", "'I am another element'");

.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}

<div class="box"></div>
<div class="box"></div>

4) Verwendung von jQuery

$('.box').eq(0).css("--color", "blue");
/* the css() function with custom properties works only with a jQuery vesion >= 3.x
   with older version we can use style attribute to set the value. Simply pay
   attention if you already have inline style defined! 
*/
$('.box').eq(1).attr("style","--color:#f0f");

.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>

Sie kann auch mit komplexen Werten verwendet werden:

.box {
  --c:"content";
  --b:linear-gradient(red,blue);
  --s:20px;
  --p:0 15px;
}

.box:before {
  content: var(--c);
  background:var(--b);
  color:#fff;
  font-size: calc(2 * var(--s) + 5px);
  padding:var(--p);
}

<div class="box"></div>

Sie werden feststellen, dass ich die Syntax var(--c,value) donde value ist der Standardwert und wird auch als Rückfallwert bezeichnet.

Aus der gleichen Spezifikation können wir lesen:

Der Wert einer benutzerdefinierten Eigenschaft kann mit der Funktion var() durch den Wert einer anderen Eigenschaft ersetzt werden. Die Syntax von var() lautet:

var() = var( <custom-property-name> [, <declaration-value> ]? )

Das erste Argument der Funktion ist der Name der benutzerdefinierten Eigenschaft, die ersetzt werden soll. Das zweite Argument der Funktion ist, falls vorhanden, ein Rückfallwert, der als Ersetzungswert verwendet wird wenn die referenzierte benutzerdefinierte Eigenschaft ungültig ist.

Und später:

Eine var() im Wert einer Eigenschaft zu ersetzen:

  1. Wenn die benutzerdefinierte Eigenschaft, die durch das erste Argument des Befehls var() Funktion ist animationsbehaftet, und die var() Funktion in der Animationseigenschaft oder einer ihrer Langschriften verwendet wird, behandeln Sie die benutzerdefinierte Eigenschaft für den Rest dieses Algorithmus als ihren Anfangswert.
  2. Wenn der Wert der benutzerdefinierten Eigenschaft, die durch das erste Argument des Befehls var() Funktion etwas anderes als der Anfangswert ist, ersetzen Sie die var() Funktion durch den Wert der entsprechenden benutzerdefinierten Eigenschaft.
  3. Andernfalls, wenn die var() Funktion einen Fallback-Wert als zweites Argument hat, ersetzen Sie die var() Funktion durch den Fallback-Wert. Wenn es irgendwelche var() Referenzen im Fallback, ersetzen Sie diese ebenfalls.
  4. Andernfalls wird die Eigenschaft, die die var() Funktion ist zum Zeitpunkt der Berechnung des Wertes ungültig.

Wenn wir die benutzerdefinierte Eigenschaft nicht festlegen ODER sie auf initial ODER er enthält einen ungültigen Wert, dann wird der Ausweichwert verwendet. Die Verwendung von initial kann hilfreich sein, wenn wir eine benutzerdefinierte Eigenschaft auf ihren Standardwert zurücksetzen wollen.

Verwandte Seiten

Wie speichert man einen geerbten Wert in einer CSS-Variablen (auch benutzerdefinierte Eigenschaft genannt)?

Benutzerdefinierte CSS-Eigenschaften (Variablen) für das Box-Modell

93voto

Gustavo Sousa Punkte 999

Pseudoelemente können in jQuery nicht ausgewählt werden, da sie nicht Teil des DOM sind. Aber Sie können dem übergeordneten Element eine bestimmte Klasse hinzufügen und seine Pseudoelemente in CSS steuern.

BEISPIEL

In jQuery:

<script type="text/javascript">
    $('span').addClass('change');
</script>

In CSS:

span.change:after { content: 'bar' }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X