Frage Auswählen und Bearbeiten von CSS-Pseudoelementen wie :: before und :: nach der Verwendung von jQuery


Gibt es eine Möglichkeit, CSS-Pseudo-Elemente wie z ::before und ::after (und die alte Version mit einem Semikolon) mit jQuery?

Zum Beispiel hat mein Stylesheet die folgende Regel:

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

Wie kann ich 'foo' mit jQuery in 'bar' ändern?


782
2018-02-18 12:53


Ursprung


Antworten:


Sie können den Inhalt auch mit einem Datenattribut an das Pseudoelement übergeben und dann mithilfe von jQuery Folgendes ändern:

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 möchten, dass der "andere Text" angezeigt wird, können Sie dies wie folgt mit der Lösung von seucolega 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';
}

606
2018-04-20 17:59



Sie würden denken, dass dies eine einfache Frage zu beantworten wäre, mit allem, was jQuery tun kann. Leider ist das Problem auf ein technisches Problem zurückzuführen: css: after und: before rules sind nicht Teil des DOM, und kann daher nicht mit den DOM-Methoden von jQuery geändert werden.

Dort sind Möglichkeiten, diese Elemente mit JavaScript und / oder CSS-Problemumgehungen zu bearbeiten; Welche Sie verwenden, hängt von Ihren genauen Anforderungen ab.


Ich fange mit dem an, was allgemein als der "beste" Ansatz gilt:

1) Hinzufügen / Entfernen einer vorbestimmten Klasse

Bei diesem Ansatz haben Sie bereits eine Klasse in Ihrem CSS mit einer anderen erstellt :after oder :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 einfach mit jQuery (oder Vanilla JavaScript) 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 gleichzeitig; erzwingt Trennung von Bedenken (isoliert Ihr CSS und JS von Ihrem HTML)
  • Nachteile: CSS muss vorab geschrieben sein, also der Inhalt von :before oder :after ist nicht vollständig dynamisch

2) Fügen Sie neue Styles direkt in das Stylesheet des Dokuments ein

Es ist möglich, JavaScript zu verwenden, um Stile direkt zum Dokument-Stylesheet hinzuzufügen, einschließlich :after und :before Stile. jQuery bietet keine bequeme Verknüpfung, 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 das verwandte .insertRule() Methoden sind heute ziemlich gut unterstützt.

Als Variante können Sie auch jQuery verwenden, um dem Dokument ein völlig neues Stylesheet hinzuzufügen, aber der 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 wir davon sprechen, die Werte zu "manipulieren", nicht nur zu ergänzen, können wir auch lesen die bestehende :after oder :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') mit $('p')[0] bei Verwendung von jQuery für etwas kürzeren Code.

  • Vorteile: Jede Zeichenfolge kann dynamisch in den Stil eingefügt werden
  • Nachteile: Originalstile werden nicht verändert, nur überschrieben; Wiederholte (ab) Verwendung kann das DOM beliebig groß werden lassen

3) Ändern Sie ein anderes DOM-Attribut

Sie können auch benutzen attr() in deinem CSS um ein bestimmtes DOM-Attribut zu lesen. (Wenn ein Browser dies unterstützt :before, es unterstützt attr() auch.) Durch die Kombination mit content:in einigen sorgfältig vorbereiteten CSS können wir den Inhalt ändern (aber keine anderen Eigenschaften, wie Rand oder Farbe) von :before und :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 rechtzeitig vorbereitet 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 auf Inhaltszeichenfolgen angewendet werden, nicht auf URLs oder RGB-Farben

391
2018-02-11 18:14



Obwohl sie von Browsern über CSS gerendert werden, als wären sie wie andere echte DOM-Elemente, sind Pseudo-Elemente selbst nicht Teil des DOM, da Pseudo-Elemente, wie der Name andeutet, keine echten Elemente sind und daher nicht selektiere und manipuliere sie direkt mit jQuery (oder irgendein JavaScript APIs für diese Angelegenheit, nicht einmal die Selektoren-API). Dies gilt für alle Pseudo-Elemente, deren Stile Sie mit einem Skript ändern möchten, und nicht nur ::before und ::after.

Der direkte Zugriff auf Pseudo-Element-Styles kann zur Laufzeit nur über das CSSOM erfolgen (think window.getComputedStyle()), die von jQuery darüber hinaus nicht offen gelegt wird .css(), eine Methode, die auch keine Pseudo-Elemente unterstützt.

Sie können jedoch immer andere Möglichkeiten finden, zum Beispiel:

  • Anwenden der Stile auf die Pseudo-Elemente einer oder mehrerer beliebiger Klassen und dann Umschalten zwischen den Klassen (siehe Seucolegas Antwort für ein schnelles Beispiel) - das ist die idiomatische Art, wie es einfache Selektoren verwendet (welche Pseudo-Elemente nicht sind), um zwischen Elementen und Elementzuständen zu unterscheiden, wie sie verwendet werden sollen

  • Manipulieren der Stile, die auf diese Pseudo-Elemente angewendet werden, durch Ändern des Dokumenten-Stylesheets, das viel mehr ein Hack ist


144
2018-02-18 12:56



Sie können Pseudoelemente in jQuery nicht auswählen, da sie nicht Teil von DOM sind. Sie können dem vater-Element jedoch eine bestimmte Klasse hinzufügen und seine Pseudo-Elemente in CSS steuern.

BEISPIEL

In jQuery:

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

In CSS:

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

72
2018-03-17 06:46



In der Linie dessen, was Christian vorschlägt, könntest du auch Folgendes tun:

$('head').append("<style>.span::after{ content:'bar' }</style>");

34
2017-10-18 10:20



Hier ist der Zugriff auf: after und: before style properties, die in css definiert sind:

// Get the color value of .element:before
var color = window.getComputedStyle(
    document.querySelector('.element'), ':before'
).getPropertyValue('color');

// Get the content value of .element:before
var content = window.getComputedStyle(
    document.querySelector('.element'), ':before'
).getPropertyValue('content');

20
2017-07-15 21:55



Ich habe diese Frage beantwortet Hier schon, aber um super cool zu sein werde ich mich für dich wiederholen.

Die Antwort sollte sein Ja Nein. Sie können kein Element über den Pseudo-Selektor auswählen, aber Sie können Ihrem Stylesheet eine neue Regel mit Javascript hinzufügen.

Ich habe etwas gemacht, das für dich funktionieren sollte:

var addRule = function(sheet, selector, styles) {
    if (sheet.insertRule) return sheet.insertRule(selector + " {" + styles + "}", sheet.cssRules.length);
    if (sheet.addRule) return sheet.addRule(selector, styles);
};

addRule(document.styleSheets[0], "body:after", "content: 'foo'");

http://fiddle.jshell.net/MDyxg/1/


12
2018-05-12 12:18



Wenn Sie die :: before oder :: after sudo Elemente vollständig über CSS bearbeiten wollen, können Sie JS verwenden. Siehe unten;

jQuery('head').append('<style id="mystyle" type="text/css"> /* your styles here */ </style>');

Beachten Sie, wie die <style> element hat eine ID, mit der Sie es entfernen und erneut anhängen können, wenn sich Ihr Stil dynamisch ändert.

Auf diese Weise ist Ihr Element Stil, genau wie Sie es durch CSS wollen, mit Hilfe von JS.


11
2018-06-14 20:13