Wybieranie i manipulowanie pseudoelementami CSS, takimi jak :: przed i :: po użyciu jQuery


943

Czy jest jakiś sposób wybierania / manipulowania pseudoelementami CSS, takimi jak ::beforei ::after(oraz stara wersja z jednym średnikiem) za pomocą jQuery?

Na przykład mój arkusz stylów ma następującą zasadę:

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

Jak zmienić „foo” na „bar” za pomocą jQuery?


4
Zrobiłem coś, co powinno Ci pomóc
yckart

1
Nienawidzę takich komentarzy na temat przepełnienia stosu, które zamierzam napisać (gdzie komentator pyta, dlaczego nie zrobisz tego w zupełnie odwrotny sposób? ), Ale: w pewnym momencie należy zdać sobie sprawę z problemu projektowania kodu i zastąpić ten pseudo element rozpiętość czy coś. Chyba wiesz, na co wskazuję.
zsitro

1
Zaakceptowana odpowiedź jest doskonała. Chociaż jeśli próbujesz osiągnąć jeden z poniższych punktów, odpowiedź nie zadziała: 1. zmień styl: przed JS. 2. Zmień treść: wcześniej przez JS Proszę zobaczyć moją odpowiedź na to, jeśli potrzebujesz.
Uczeń


@ Uczeń Teraz istnieje odpowiedź na wszystkie z nich: stackoverflow.com/a/49618941/8620333
Temani Afif

Odpowiedzi:


694

Możesz także przekazać zawartość do pseudoelementu z atrybutem danych, a następnie użyć jQuery do manipulowania tym:

W HTML:

<span>foo</span>

W jQuery:

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

W CSS:

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

Jeśli chcesz zapobiec wyświetlaniu się „innego tekstu”, możesz połączyć to z rozwiązaniem seucolega w następujący sposób:

W HTML:

<span>foo</span>

W jQuery:

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

W CSS:

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

2
Czy masz w specyfikacji link do używania tej attrfunkcji przeciwko contentwłaściwości? Dziwi mnie, że nigdy o tym nie słyszałem ...
Kevin Peno

95
+1 za attr(), szkoda, że ​​nie mogłem użyć go z innymi właściwościami niż content. Demo
Maksim Vi.

28
Jest tak, ponieważ żadna przeglądarka jeszcze nie zaimplementowała attr()poza CSS2, podczas gdy w CSS2 attr()została zdefiniowana tylko dla tej contentwłaściwości.
BoltClock

10
Zaktualizowany link do odniesień do atrybutów: w3.org/TR/css3-values/#attr-notation


477

Można by pomyśleć, że byłoby to proste pytanie, na które można odpowiedzieć, ze wszystkim innym, co może zrobić jQuery. Niestety problem sprowadza się do problemu technicznego: css: after i: before reguły nie są częścią DOM i dlatego nie można ich zmienić za pomocą metod DOM jQuery.

Tam sposoby, aby manipulować tych elementów przy użyciu JavaScript i / lub CSS obejścia; to, którego używasz, zależy od twoich dokładnych wymagań.


Zacznę od tego, co jest powszechnie uważane za „najlepsze” podejście:

1) Dodaj / usuń z góry określoną klasę

W tym podejściu stworzyłeś już klasę w swoim CSS w innym stylu :afterlub :beforestylu. Umieść tę „nową” klasę później w arkuszu stylów, aby upewnić się, że zastępuje:

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

Następnie możesz łatwo dodać lub usunąć tę klasę za pomocą jQuery (lub waniliowego JavaScript):

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

  • Plusy: Łatwy do wdrożenia dzięki jQuery; szybko zmienia wiele stylów jednocześnie; wymusza separację problemów (izolowanie CSS i JS od HTML)
  • Minusy: CSS musi być wcześniej napisany, więc zawartość :beforelub :afternie jest całkowicie dynamiczna

2) Dodaj nowe style bezpośrednio do arkusza stylów dokumentu

Możliwe jest użycie JavaScript do dodawania stylów bezpośrednio do arkusza stylów dokumentu, w tym stylów :afteri :before. jQuery nie zapewnia wygodnego skrótu, ale na szczęście JS nie jest tak skomplikowany:

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

.addRule()a pokrewne .insertRule()metody są dziś dość dobrze wspierane.

Jako wariant możesz również użyć jQuery, aby dodać do dokumentu zupełnie nowy arkusz stylów, ale niezbędny kod nie jest bardziej przejrzysty:

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

Jeśli mówimy o „manipulowaniu” wartościami, a nie tylko ich dodawaniu, możemy również odczytać istniejące :afterlub :beforestyle, stosując inne podejście:

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

Możemy wymienić document.querySelector('p')z $('p')[0]przy użyciu jQuery, dla nieco krótszy kod.

  • Plusy: każdy ciąg może być dynamicznie wstawiany do stylu
  • Minusy: oryginalne style nie są zmieniane, tylko nadpisywane; wielokrotne użycie (ab) może spowodować dowolną rozbudowę DOM

3) Zmień inny atrybut DOM

Możesz także użyć attr()w swoim CSS do odczytania określonego atrybutu DOM. ( Jeśli przeglądarka obsługuje :before, obsługuje attr()również. ) Łącząc to z content:starannie przygotowanym CSS, możemy zmieniać zawartość (ale nie inne właściwości, takie jak margines lub kolor) :beforei :afterdynamicznie:

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

JS:

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

Można to połączyć z drugą techniką, jeśli CSS nie może zostać przygotowany wcześniej:

var str = "bar";

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

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

  • Plusy: Nie tworzy nieskończonych dodatkowych stylów
  • Minusy: attr w CSS można stosować tylko do ciągów treści, a nie adresów URL lub kolorów RGB

2
Próbuję dynamicznie ustawiać wartości glifikonu (tj. Poprzez ich wartości szesnastkowe) w :: po psedo. content: element (np. content: „\ e043”;). wydaje się, że to nie działa dla mnie, więc zakładam, że nie działa również dla wartości szesnastkowych dla glifikonów?
user2101068,

@ user2101068 Powinieneś opublikować to jako nowe pytanie. Musiałbym zobaczyć cały kod, którego używasz.
Blazemonger,

Blazemonger, dzięki za szybką odpowiedź .. niestety jest sporo kodu i zajęłoby sporo wysiłku, aby wyciąć odpowiedni kod. Spędziłem już ponad 12 godzin próbując zdobyć tę pracę i to był mój ostatni trudny wysiłek, aby ją uruchomić. Muszę zmniejszyć straty. Miałem nadzieję, że możesz po prostu zweryfikować moje założenia re: wartości szesnastkowe podczas korzystania z techniki opisanej w punkcie 3 powyżej (przed fragmentem kodu). Mogę wstawić ciąg heksadecymalny do elementu treści, ale wyświetla on tekst dla wartości heksadecyficznej zamiast glifikonu. Wrażenie bez zobaczenia całego kodu?
user2101068,

1
@ user2101068 Nie używaj ciągu szesnastkowego; zamiast tego skopiuj i wklej rzeczywisty znak Unicode do atrybutu HTML. jsfiddle.net/mblase75/Lcsjkc5y
Blazemonger

w odniesieniu do rozwiązania 2. i 3. faktycznie możesz zapobiec (nadmiernemu) wzrostowi arkusza stylów, jeśli użyjesz: document.styleSheets [0] .insertRule (reguła, indeks), a następnie korzystając z tego indeksu możesz usunąć reguły, gdy nie będą potrzebne: dokument. styleSheets [0] .deleteRule (index)
Picard

158

Chociaż są renderowane przez przeglądarki za pomocą CSS, tak jakby były jak inne prawdziwe elementy DOM, same pseudoelementy nie są częścią DOM, ponieważ pseudoelementy, jak sama nazwa wskazuje, nie są prawdziwymi elementami, a zatem nie można zaznacz i manipuluj nimi bezpośrednio za pomocą jQuery (lub dowolnych API JavaScript w tym zakresie, nawet API Selektorów ). Dotyczy to wszystkich pseudoelementów, których style próbujesz zmodyfikować za pomocą skryptu, a nie tylko ::beforei ::after.

Możesz uzyskać dostęp do stylów pseudoelementów bezpośrednio w czasie wykonywania za pośrednictwem CSSOM (think window.getComputedStyle()), który nie jest ujawniony przez jQuery poza .css(), metoda, która nie obsługuje również pseudoelementów.

Zawsze możesz jednak znaleźć inne sposoby, na przykład:

  • Zastosowanie stylów do pseudoelementów jednej lub więcej dowolnych klas, a następnie przełączanie między klasami (patrz szybki odpowiedź seucolegi ) - jest to idiomatyczny sposób, ponieważ wykorzystuje on proste selektory (których pseudoelementami nie są), aby rozróżniać elementy i stany elementów, sposób, w jaki są przeznaczone do użycia

  • Manipulowanie stylami stosowanymi do wspomnianych pseudoelementów poprzez zmianę arkusza stylów dokumentu, co jest znacznie bardziej włamaniem


78

Nie możesz wybrać pseudoelementów w jQuery, ponieważ nie są one częścią DOM. Ale możesz dodać określoną klasę do elementu ojca i kontrolować jego pseudoelementy w CSS.

PRZYKŁAD

W jQuery:

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

W CSS:

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

48

Możemy również polegać na niestandardowych właściwościach (zwanych również zmiennymi CSS) w celu manipulowania pseudoelementem. W specyfikacji możemy przeczytać, że:

Właściwości niestandardowe są zwykłymi właściwościami, więc można je zadeklarować w dowolnym elemencie, są rozwiązywane przy użyciu normalnych reguł dziedziczenia i kaskadowych , mogą być warunkowane za pomocą @media i innych reguł warunkowych, mogą być używane w atrybucie stylu HTML , mogą być odczytywane lub ustawiane za pomocą CSSOM itp.

Biorąc to pod uwagę, chodzi o zdefiniowanie niestandardowej właściwości w elemencie, a pseudoelement po prostu odziedziczy ją; dzięki czemu możemy go łatwo modyfikować.

1) Używając stylu wbudowanego :

.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) Korzystanie z CSS i klas

.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) Za pomocą 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) Korzystanie z 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>


Może być również stosowany ze złożonymi wartościami:

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

Możesz zauważyć, że rozważam składnię, w var(--c,value)której valuejest wartością domyślną, a także nazywaną wartością rezerwową.

Z tej samej specyfikacji możemy odczytać:

Wartość właściwości niestandardowej można zastąpić wartością innej właściwości za pomocą funkcji var (). Składnia var () jest następująca:

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

Pierwszym argumentem funkcji jest nazwa właściwości niestandardowej, która ma zostać podstawiona. Drugi argument funkcji, jeśli ją podano, to wartość zastępcza, która jest używana jako wartość podstawienia, gdy odwołana właściwość niestandardowa jest nieprawidłowa.

I później:

Aby podstawić zmienną var () w wartości właściwości:

  1. Jeśli właściwość niestandardowa nazwana pierwszym argumentem var()funkcji jest skażona animacją, a var()funkcja jest używana we właściwości animacji lub w jednym z jej długich dłoni, należy traktować właściwość niestandardową jako mającą wartość początkową dla pozostałej części tego algorytmu.
  2. Jeśli wartość właściwości niestandardowej nazwanej pierwszym argumentem var()funkcji jest inna niż wartość początkowa, zastąp var()funkcję wartością odpowiedniej właściwości niestandardowej.
  3. W przeciwnym razie, jeśli var()funkcja ma wartość zastępczą jako drugi argument, zamień var()funkcję na wartość zastępczą. Jeśli var()w rezerwowym są jakieś odniesienia, również je zastąp.
  4. W przeciwnym razie właściwość zawierająca var()funkcję jest niepoprawna w czasie wartości obliczonej.

Jeśli nie ustawimy niestandardowej właściwości LUB ustawimy ją na initialLUB zawiera ona niepoprawną wartość, wówczas zostanie użyta wartość zastępcza. Użycie initialmoże być pomocne na wypadek, gdybyśmy chcieli zresetować właściwość niestandardową do jej wartości domyślnej.

Związane z

Jak przechowywać wartość odziedziczoną w niestandardowej właściwości CSS (znanej również jako zmienne CSS)?

Niestandardowe właściwości CSS (zmienne) dla modelu pudełkowego


Pamiętaj, że zmienne CSS mogą nie być dostępne we wszystkich przeglądarkach, które uważasz za istotne (np. IE 11): https://caniuse.com/#feat=css-variables


@akalata tak, kod wymaga jQuery w wersji 3.x .. Dodałem więcej szczegółów i kolejną alternatywę dla jQuery;)
Temani Afif

Jak miałoby to działać w IE 11?
connexo

1
@connexo jak każda dobra i nowoczesna funkcja .. nie jest obsługiwana i nie będzie działać caniuse.com/#feat=css-variables
Temani Afif

Oczywiście wiedziałem o tym, a ponieważ IE 11 jest nadal bardzo istotny, brakowało mi tej informacji bezpośrednio we wstępnej części twojej odpowiedzi.
connexo

1
Ta odpowiedź to dogłębny samouczek dotyczący powiązania i modyfikacji pseudoelementów za pomocą JavaScript za pomocą Zmiennych CSS. Bardzo dziękuję za poświęcony czas i za udostępnienie tej niezwykle cennej techniki.
LebCit

37

Zgodnie z tym, co sugeruje Christian, możesz także:

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

2
Tutaj należy dodać atrybut id, aby element mógł zostać wybrany i usunięty przed dodaniem nowego. Jeśli nie, może pojawić się wiele niepotrzebnych węzłów stylu.
KS

24

Oto sposób dostępu: po i: przed właściwościami stylu, zdefiniowanymi w css:

// 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');

11

Jeśli chcesz manipulować elementami :: przed lub :: po sudo całkowicie za pomocą CSS, możesz to zrobić JS. Patrz poniżej;

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

Zauważ, jak <style> element ma identyfikator, którego możesz użyć, aby go usunąć i dołączyć do niego ponownie, jeśli styl zmieni się dynamicznie.

W ten sposób twój element jest stylem dokładnie tak, jak chcesz za pomocą CSS, z pomocą JS.


6

jednym działającym, ale niezbyt wydajnym sposobem jest dodanie reguły do ​​dokumentu z nową zawartością i odniesienie go do klasy. w zależności od potrzeb klasa może potrzebować unikalnego identyfikatora dla każdej wartości w treści.

$("<style type='text/css'>span.id-after:after{content:bar;}</style>").appendTo($("head"));
$('span').addClass('id-after');

5

Oto HTML:

<div class="icon">
  <span class="play">
    ::before
  </span>
</div>

Obliczony styl „przed” był content: "VERIFY TO WATCH";

Oto moje dwa wiersze jQuery, które wykorzystują pomysł dodania dodatkowej klasy, aby konkretnie odwoływać się do tego elementu, a następnie dodania tagu stylu (z! Ważnym znacznikiem), aby zmienić CSS wartości zawartości elementu sudo:

$("span.play:eq(0)").addClass('G');

$('body').append("<style>.G:before{content:'NewText' !important}</style>");


5

Dziękuję wam wszystkim! udało mi się zrobić to, co chciałem: D http://jsfiddle.net/Tfc9j/42/ tutaj spójrz

chciałem, aby krycie zewnętrznego div różniło się od krycia wewnętrznego div, a ta zmiana gdzieś kliknięciem;) Dzięki!

   $('#ena').on('click', function () {
        $('head').append("<style>#ena:before { opacity:0.3; }</style>");
    });

$('#duop').on('click', function (e) {

        $('head').append("<style>#ena:before { opacity:0.8; }</style>");

     e.stopPropagation(); 
    });

#ena{
    width:300px;
    height:300px;
    border:1px black solid;
    position:relative;
}
#duo{
    opacity:1;
    position:absolute;
    top:50px;
  width:300px;
    height:100px;
      background-color:white;
}
#ena:before {
    content: attr(data-before);
    color: white;
    cursor: pointer;
    position: absolute;
    background-color:red;
    opacity:0.9;
    width:100%;
    height:100%;
}


<div id="ena">
    <div id="duo">
        <p>ena p</p>
        <p id="duop">duoyyyyyyyyyyyyyy p</p>

    </div>   


</div>

Nie próbuj append, htmlnajlepiej jest unikać
używania

1
Uważaj: tutaj dodajesz tag stylu do głowy za każdym razem, gdy obsługiwane jest jedno z tych kliknięć. Kodowałbym sposób usunięcia starego przed dodaniem nowego.
pupitetris

3

Możesz utworzyć fałszywą właściwość lub użyć istniejącej i odziedziczyć ją w arkuszu stylów pseudoelementu.

var switched = false;

// Enable color switching
setInterval(function () {
    var color = switched ? 'red' : 'darkred';
    var element = document.getElementById('arrow');
    element.style.backgroundColor = color;
    
    // Managing pseudo-element's css
    // using inheritance.
    element.style.borderLeftColor = color;
    
    switched = !switched;
}, 1000);
.arrow {
    /* SET FICTIONAL PROPERTY */
    border-left-color:red;
    
    background-color:red;
    width:1em;
    height:1em;
    display:inline-block;
    position:relative;
}
.arrow:after {
    border-top:1em solid transparent;
    border-right:1em solid transparent;
    border-bottom:1em solid transparent;
    border-left:1em solid transparent;
    
    /* INHERIT PROPERTY */
    border-left-color:inherit;
    
    content:"";
    width:0;
    height:0;
    position:absolute;
    left:100%;
    top:-50%;
}
<span id="arrow" class="arrow"></span>

Wygląda na to, że nie działa dla właściwości „content” :(


3

Nie jest to praktyczne, ponieważ nie napisałem tego do użytku w prawdziwym świecie, aby dać przykład tego, co można osiągnąć.

css = {
before: function(elem,attr){ 

if($("#cust_style") !== undefined){ 
$("body").append("<style> " + elem + ":before {"  + attr +  "} </style>"); 
} else {
 $("#cust_style").remove();
$("body").append("<style> " + elem + ":before {"  + attr +  "} </style>"); 
}

}, after: function(elem,attr){
if($("#cust_style") !== undefined){ 
$("body").append("<style> " + elem + ":after {"  + attr +  "} </style>"); 

} else { $("#cust_style").remove();
$("body").append("<style> " + elem + ":after {"  + attr +  "} </style>"); 
}
}
}

ten dodatek dodaje a / lub dołącza element Style, który zawiera niezbędne atrybuty, które będą miały wpływ na element docelowy po elemencie Pseudo.

można to wykorzystać jako

css.after("someElement"," content: 'Test'; position: 'absolute'; ") // editing / adding styles to :after

i

css.before( ... ); // to affect the before pseudo element.

ponieważ po: i przed: pseudoelementy nie są dostępne bezpośrednio przez DOM, obecnie nie można swobodnie edytować określonych wartości css.

mój sposób był tylko przykładem i nie jest dobry do praktyki, możesz go zmodyfikować, wypróbować własne triki i dostosować do użytku w świecie rzeczywistym.

więc zróbcie własne eksperymenty z tym i innymi!

pozdrowienia - Adarsh ​​Hegde.


3

Zawsze dodaję własną funkcję utils, która wygląda tak.

function setPseudoElContent(selector, value) {    
    document.styleSheets[0].addRule(selector, 'content: "' + value + '";');
}

setPseudoElContent('.class::after', 'Hello World!');

lub skorzystaj z funkcji ES6:

const setPseudoElContent = (selector, value) => {    
    document.styleSheets[0].addRule(selector, `content: "${value}";`);
}

setPseudoElContent('.class::after', 'Hello World!');

2

Po co dodawać klasy lub atrybuty, skoro można po prostu dołączyć styledo nagłówka

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

2

Istnieje wiele odpowiedzi tutaj, ale żadna odpowiedź nie pomaga w manipulowaniu css :beforelub :afternawet tej zaakceptowanej.

Oto jak proponuję to zrobić. Załóżmy, że Twój HTML wygląda następująco:

<div id="something">Test</div>

A potem ustawiasz jej: wcześniej w CSS i projektujesz tak:

#something:before{
   content:"1st";
   font-size:20px;
   color:red;
}
#something{
  content:'1st';
}

Zauważ, że ustawiłem także contentatrybut w samym elemencie, abyś mógł go później łatwo usunąć. Teraz jestbutton kliknięcie, na którym chcesz zmienić kolor: przed na zielony i jego rozmiar czcionki na 30px. Możesz to osiągnąć w następujący sposób:

Zdefiniuj css z wymaganym stylem w niektórych klasach .activeS:

.activeS:before{
   color:green !important;
   font-size:30px !important;
 }

Teraz możesz zmienić: przed stylem, dodając klasę do elementu: przed w następujący sposób:

<button id="changeBefore">Change</button>
<script>
    $('#changeBefore').click(function(){
        $('#something').addClass('activeS');
    });
</script>

Jeśli chcesz tylko uzyskać treść :before, możesz to zrobić jako:

<button id="getContent">Get Content</button>
<script>
    $('#getContent').click(function(){
        console.log($('#something').css('content'));//will print '1st'
    });
</script>

Ostatecznie, jeśli chcesz dynamicznie zmieniać :beforezawartość za pomocą jQuery, możesz to osiągnąć w następujący sposób:

<button id="changeBefore">Change</button>
<script>
    var newValue = '22';//coming from somewhere
    var add = '<style>#something:before{content:"'+newValue+'"!important;}</style>';
    $('#changeBefore').click(function(){
        $('body').append(add);
    });
</script>

Kliknięcie powyższego przycisku „zmień przed” spowoduje zmianę :beforezawartości #somethingna „22”, co jest wartością dynamiczną.

Mam nadzieję, że to pomoże


1

Wykorzystałem zmienne zdefiniowane w :rootśrodku, CSSaby zmodyfikować pseudoelement:after (to samo dotyczy :before) , w szczególności aby zmienić wartość stylu zdefiniowanego przez i wartość innej ( ) w poniższym demo, które generuje losowe kolory za pomocą JavaScript / jQuery:background-coloranchor.sliding-middle-out:hover:aftercontentanchor#reference

HTML

<a href="#" id="changeColor" class="sliding-middle-out" title="Generate a random color">Change link color</a>
<span id="log"></span>
<h6>
  <a href="https://stackoverflow.com/a/52360188/2149425" id="reference" class="sliding-middle-out" target="_blank" title="Stack Overflow topic">Reference</a>
</h6>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/davidmerfield/randomColor/master/randomColor.js"></script>

CSS

:root {
    --anchorsFg: #0DAFA4;
}
a, a:visited, a:focus, a:active {
    text-decoration: none;
    color: var(--anchorsFg);
    outline: 0;
    font-style: italic;

    -webkit-transition: color 250ms ease-in-out;
    -moz-transition: color 250ms ease-in-out;
    -ms-transition: color 250ms ease-in-out;
    -o-transition: color 250ms ease-in-out;
    transition: color 250ms ease-in-out;
}
.sliding-middle-out {
    display: inline-block;
    position: relative;
    padding-bottom: 1px;
}
.sliding-middle-out:after {
    content: '';
    display: block;
    margin: auto;
    height: 1px;
    width: 0px;
    background-color: transparent;

    -webkit-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -moz-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -ms-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -o-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
}
.sliding-middle-out:hover:after {
    width: 100%;
    background-color: var(--anchorsFg);
    outline: 0;
}
#reference {
  margin-top: 20px;
}
.sliding-middle-out:before {
  content: attr(data-content);
  display: attr(data-display);
}

JS / jQuery

var anchorsFg = randomColor();
$( ".sliding-middle-out" ).hover(function(){
    $( ":root" ).css({"--anchorsFg" : anchorsFg});
});

$( "#reference" ).hover(
 function(){
    $(this).attr("data-content", "Hello World!").attr("data-display", "block").html("");
 },
 function(){
    $(this).attr("data-content", "Reference").attr("data-display", "inline").html("");
 }
);

Wsparcie dla attr()wyjątku z wyjątkiem contentjest naprawdę rzadkie. Możesz to sprawdzić w caniuse.com. :rootObsługa zmiennych css jest lepsza, ale nadal nie jest tak szeroko rozpowszechniona, ponieważ obsługa jest całkiem nowa. (sprawdź także wsparcie na caniuse.com)
BananaAcid

1

Stworzyłem wtyczkę jQuery, aby dodać pseudo reguły css, takie jak używanie .css()dla określonych elementów.

  • kod wtyczki i przypadek testowy są tutaj
  • użyj przypadku jako prostego wyskakującego obrazu css tutaj

stosowanie:

$('body')
  .css({
    backgroundColor: 'white'
  })
  .cssPseudo('after', {
    content: 'attr(title) ", you should try to hover the picture, then click it."',
    position: 'absolute',
    top: 20, left: 20  
  })
  .cssPseudo('hover:after', {
    content: '"Now hover the picture, then click it!"'
  });

0

 $('.span').attr('data-txt', 'foo');
        $('.span').click(function () {
         $(this).attr('data-txt',"any other text");
        })
.span{
}
.span:after{ 
  content: attr(data-txt);
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='span'></div>


0

Możesz użyć mojej wtyczki do tego celu.

JQuery:

(function() {
  $.pseudoElements = {
    length: 0
  };

  var setPseudoElement = function(parameters) {
    if (typeof parameters.argument === 'object' || (parameters.argument !== undefined && parameters.property !== undefined)) {
      for (var element of parameters.elements.get()) {
        if (!element.pseudoElements) element.pseudoElements = {
          styleSheet: null,
          before: {
            index: null,
            properties: null
          },
          after: {
            index: null,
            properties: null
          },
          id: null
        };

        var selector = (function() {
          if (element.pseudoElements.id !== null) {
            if (Number(element.getAttribute('data-pe--id')) !== element.pseudoElements.id) element.setAttribute('data-pe--id', element.pseudoElements.id);
            return '[data-pe--id="' + element.pseudoElements.id + '"]::' + parameters.pseudoElement;
          } else {
            var id = $.pseudoElements.length;
            $.pseudoElements.length++

              element.pseudoElements.id = id;
            element.setAttribute('data-pe--id', id);

            return '[data-pe--id="' + id + '"]::' + parameters.pseudoElement;
          };
        })();

        if (!element.pseudoElements.styleSheet) {
          if (document.styleSheets[0]) {
            element.pseudoElements.styleSheet = document.styleSheets[0];
          } else {
            var styleSheet = document.createElement('style');

            document.head.appendChild(styleSheet);
            element.pseudoElements.styleSheet = styleSheet.sheet;
          };
        };

        if (element.pseudoElements[parameters.pseudoElement].properties && element.pseudoElements[parameters.pseudoElement].index) {
          element.pseudoElements.styleSheet.deleteRule(element.pseudoElements[parameters.pseudoElement].index);
        };

        if (typeof parameters.argument === 'object') {
          parameters.argument = $.extend({}, parameters.argument);

          if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {
            var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;

            element.pseudoElements[parameters.pseudoElement].index = newIndex;
            element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;
          };

          var properties = '';

          for (var property in parameters.argument) {
            if (typeof parameters.argument[property] === 'function')
              element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();
            else
              element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];
          };

          for (var property in element.pseudoElements[parameters.pseudoElement].properties) {
            properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
          };

          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);
        } else if (parameters.argument !== undefined && parameters.property !== undefined) {
          if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {
            var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;

            element.pseudoElements[parameters.pseudoElement].index = newIndex;
            element.pseudoElements[parameters.pseudoElement].properties = {};
          };

          if (typeof parameters.property === 'function')
            element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property();
          else
            element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property;

          var properties = '';

          for (var property in element.pseudoElements[parameters.pseudoElement].properties) {
            properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
          };

          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);
        };
      };

      return $(parameters.elements);
    } else if (parameters.argument !== undefined && parameters.property === undefined) {
      var element = $(parameters.elements).get(0);

      var windowStyle = window.getComputedStyle(
        element, '::' + parameters.pseudoElement
      ).getPropertyValue(parameters.argument);

      if (element.pseudoElements) {
        return $(parameters.elements).get(0).pseudoElements[parameters.pseudoElement].properties[parameters.argument] || windowStyle;
      } else {
        return windowStyle || null;
      };
    } else {
      console.error('Invalid values!');
      return false;
    };
  };

  $.fn.cssBefore = function(argument, property) {
    return setPseudoElement({
      elements: this,
      pseudoElement: 'before',
      argument: argument,
      property: property
    });
  };
  $.fn.cssAfter = function(argument, property) {
    return setPseudoElement({
      elements: this,
      pseudoElement: 'after',
      argument: argument,
      property: property
    });
  };
})();

$(function() {
  $('.element').cssBefore('content', '"New before!"');
});
.element {
  width: 480px;
  margin: 0 auto;
  border: 2px solid red;
}

.element::before {
  content: 'Old before!';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<div class="element"></div>

Wartości należy podać, tak jak w normalnej funkcji jQuery.css

Ponadto można również uzyskać wartość parametru pseudoelementu, tak jak w normalnej funkcji jQuery.css:

console.log( $(element).cssBefore(parameter) );

JS:


GitHub: https://github.com/yuri-spivak/managing-the-properties-of-pseudo-elements/


0

Ktoś inny skomentował dołączenie do elementu head z pełnym elementem stylu i nie jest to złe, jeśli robisz to tylko raz, ale jeśli musisz go zresetować więcej niż raz, otrzymasz mnóstwo elementów stylu. Aby nie dopuścić do tego, że utworzyłem w głowie pusty element stylu z identyfikatorem i zastąpiłem jego innerHTML w następujący sposób:

<style id="pseudo"></style>

W takim razie JavaScript wygląda następująco:

var pseudo = document.getElementById("pseudo");

function setHeight() {
    let height = document.getElementById("container").clientHeight;
    pseudo.innerHTML = `.class:before { height: ${height}px; }`
}

setHeight()

Teraz w moim przypadku potrzebowałem tego, aby ustawić wysokość elementu przed w oparciu o wysokość innego, a zmieni się on przy zmianie rozmiaru, więc za pomocą tego mogę uruchomić za setHeight()każdym razem, gdy zmienia się rozmiar okna i zastąpi to <style>poprawnie.

Mam nadzieję, że to pomoże komuś, kto utknął próbując zrobić to samo.


-1

Mam dla ciebie coś innego, co jest łatwe i skuteczne.

    <style> 
    .case-after:after { // set your properties here like eg: 
        color:#3fd309 !important; 
     } 
     .case-before:before { // set your properties here like eg: 
        color:#151715 !important; 
     }
 </style>
  // case for after
    $('#button-id').on('click', function() {
        $(".target-div").toggleClass('case-after');
    });

     // case for before
    $('#button-id').on('click', function() {
        $(".target-div").toggleClass('case-before');
    });
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.