Selezione e manipolazione di pseudo-elementi CSS come :: before e :: dopo aver usato jQuery


943

Esiste un modo per selezionare / manipolare pseudo-elementi CSS come ::beforee ::after(e la vecchia versione con un punto e virgola) usando jQuery?

Ad esempio, il mio foglio di stile ha la seguente regola:

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

Come posso cambiare 'pippo' in 'bar' usando jQuery?


4
Ho fatto qualcosa che dovrebbe funzionare per te: gist.github.com/yckart/5563717
yckart

1
Odio tali commenti su StackOverflow che sto per scrivere (dove commentatore chiede perché non lo fai in un modo completamente opposto? ), Ma: a un certo punto si dovrebbe realizzare un problema di progettazione del codice e sostituire lo pseudo elemento con un span o qualcosa del genere. Immagino tu sappia a cosa sto puntando.
zsitro,

1
La risposta accettata è eccellente. Tuttavia, se stai cercando di raggiungere uno dei seguenti punti, la risposta non funzionerà: 1. cambia lo stile di: prima di JS. 2. cambia il contenuto di: before by JS Vedi la mia risposta se ne hai bisogno.
Principiante


@Learner Ora c'è una risposta per tutti questi: stackoverflow.com/a/49618941/8620333
Temani Afif

Risposte:


695

Puoi anche passare il contenuto allo pseudo elemento con un attributo data e quindi usare jQuery per manipolarlo:

In HTML:

<span>foo</span>

In jQuery:

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

Nel CSS:

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

Se si desidera impedire la visualizzazione dell'altro testo, è possibile combinare questo con la soluzione di seucolega in questo modo:

In HTML:

<span>foo</span>

In jQuery:

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

Nel CSS:

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

2
Hai un link nelle specifiche per usare quella attrfunzione contro la contentproprietà? Sono sorpreso di non aver mai sentito parlare di questo ...
Kevin Peno,

95
+1 per attr(), peccato che non sono stato in grado di usarlo con proprietà diverse da content. Demo
Maksim Vi.

28
Questo perché nessun browser esistente è stato implementato attr()oltre CSS2, mentre in CSS2 stesso attr()è stato definito solo percontent proprietà.
BoltClock

10
Link aggiornato per i riferimenti agli attributi: w3.org/TR/css3-values/#attr-notation


477

Penseresti che questa sarebbe una semplice domanda a cui rispondere, con tutto ciò che jQuery può fare. Sfortunatamente, il problema si riduce a un problema tecnico: css: after e: before le regole non fanno parte del DOM e quindi non possono essere modificate usando i metodi DOM di jQuery.

Ci sono modi per manipolare questi elementi utilizzando JavaScript e / o CSS soluzioni alternative; quale usi dipende dai tuoi esatti requisiti.


Inizierò con quello che è ampiamente considerato l'approccio "migliore":

1) Aggiungi / rimuovi una classe predeterminata

In questo approccio, hai già creato una classe nel tuo CSS con un diverso :aftero :beforestile. Inserisci questa "nuova" classe più avanti nel tuo foglio di stile per assicurarti che abbia la precedenza:

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

Quindi puoi aggiungere o rimuovere facilmente questa classe usando jQuery (o JavaScript vanilla):

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

  • Pro: facile da implementare con jQuery; modifica rapidamente più stili contemporaneamente; applica la separazione delle preoccupazioni (isolando CSS e JS dal tuo HTML)
  • Contro: CSS devono essere pre-scritti, quindi il contenuto di :beforeo :afternon è completamente dinamico

2) Aggiungi nuovi stili direttamente al foglio di stile del documento

È possibile utilizzare JavaScript per aggiungere stili direttamente al foglio di stile del documento, inclusi :aftere :beforestili. jQuery non fornisce una scorciatoia conveniente, ma per fortuna JS non è così complicato:

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

.addRule()e i relativi .insertRule()metodi sono oggi abbastanza ben supportati.

Come variante, puoi anche usare jQuery per aggiungere un foglio di stile completamente nuovo al documento, ma il codice necessario non è più pulito:

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

Se stiamo parlando di "manipolare" i valori, non solo di aggiungerli, possiamo anche leggere gli stili esistenti :aftero:before usando un approccio diverso:

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

Possiamo sostituirlo document.querySelector('p')con$('p')[0] quando si utilizza jQuery, per un codice leggermente più breve.

  • Professionisti: qualsiasi stringa può essere inserita dinamicamente nello stile
  • Contro: stili originali non vengono alterati, ma solo sostituiti; l'uso ripetuto (ab) può far crescere arbitrariamente il DOM

3) Modificare un diverso attributo DOM

Puoi anche usare attr()nel tuo CSS per leggere un particolare attributo DOM. ( Se un browser supporta :before, supporta attr()anche. ) Combinando questo con content:alcuni CSS accuratamente preparati, possiamo cambiare il contenuto (ma non altre proprietà, come margine o colore) :beforee :afterdinamicamente:

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

JS:

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

Questo può essere combinato con la seconda tecnica se il CSS non può essere preparato in anticipo:

var str = "bar";

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

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

  • Pro: non crea infiniti stili extra
  • Contro: attr nei CSS può essere applicato solo alle stringhe di contenuto, non agli URL o ai colori RGB

2
Sto cercando di impostare dinamicamente i valori glyphicon (cioè, attraverso i loro valori esadecimali) in :: after psedo. content: element (es. content: "\ e043";). non sembra funzionare per me, quindi presumo che non funzioni neanche per i valori esadecimali per i glifi?
user2101068

@ user2101068 Dovresti postarlo come una nuova domanda. Dovrei vedere tutto il codice che stai usando.
Blazemonger,

Blazemonger, grazie per la rapida risposta ... sfortunatamente c'è un bel po 'di codice e ci vorrebbe un bel po' di sforzo per estrarre il relativo codice. Ho già trascorso più di 12 ore a cercare di ottenere questo lavoro e questo è stato il mio ultimo sussulto per farlo funzionare. Ho bisogno di tagliare le mie perdite. Speravo che potessi essere in grado di verificare il mio presupposto relativamente ai valori esadecimali quando usi la tecnica che hai descritto al punto 3 sopra (prima del frammento di codice). Posso inserire una stringa esadecimale nell'elemento content, ma visualizza il testo per il valore esadecimale del glyphicon piuttosto che il glyphicon reale. Impressione senza vedere tutto il codice?
user2101068

1
@ user2101068 Non utilizzare la stringa esadecimale; invece, copia e incolla il carattere Unicode effettivo nell'attributo HTML. jsfiddle.net/mblase75/Lcsjkc5y
Blazemonger

per quanto riguarda la soluzione 2. e 3. in realtà puoi impedire la crescita (eccessiva) del foglio di stile se usi: document.styleSheets [0] .insertRule (regola, indice), quindi usando questo indice puoi rimuovere le regole quando non sono necessarie: documento. styleSheets [0] .deleteRule (indice)
Picard

158

Sebbene siano resi dai browser tramite CSS come se fossero come altri elementi DOM reali, gli stessi pseudo-elementi non fanno parte del DOM, poiché gli pseudo-elementi, come suggerisce il nome, non sono elementi reali, e quindi non è possibile selezionarli e manipolarli direttamente con jQuery (o qualsiasi API JavaScript per quella materia, nemmeno l' API Selettori ). Questo vale per tutti gli pseudo-elementi di cui stai provando a modificare gli stili con uno script e non solo ::beforee::after .

Puoi accedere agli stili di pseudo-elementi solo direttamente in fase di esecuzione tramite CSSOM (pensa window.getComputedStyle() ), che non è esposto da jQuery oltre.css() , un metodo che non supporta neanche pseudo-elementi.

Puoi sempre trovare altri modi per aggirarlo, ad esempio:

  • Applicare gli stili agli pseudo-elementi di una o più classi arbitrarie, quindi passare da una classe all'altra (vedere la risposta di seucolega per un rapido esempio): questo è il modo idiomatico in cui si avvale di semplici selettori (a cui gli pseudo-elementi non sono) distinguere tra elementi e stati degli elementi, il modo in cui sono destinati a essere utilizzati

  • Manipolare gli stili applicati a detti pseudo-elementi, alterando il foglio di stile del documento, che è molto più di un hack


78

Non è possibile selezionare pseudo elementi in jQuery perché non fanno parte di DOM. Ma puoi aggiungere una classe specifica all'elemento padre e controllare i suoi pseudo elementi nei CSS.

ESEMPIO

In jQuery:

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

Nel CSS:

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

48

Possiamo anche fare affidamento su proprietà personalizzate (ovvero variabili CSS) per manipolare lo pseudo-elemento. Possiamo leggere nelle specifiche che:

Le proprietà personalizzate sono proprietà ordinarie, quindi possono essere dichiarate su qualsiasi elemento, vengono risolte con la normale eredità e cascata regole di , possono essere condizionate con @media e altre regole condizionali, possono essere utilizzate nell'attributo di stile HTML , possono essere lette o impostate usando la CSSOM , ecc.

Considerando ciò, l'idea è quella di definire la proprietà personalizzata all'interno dell'elemento e lo pseudo-elemento lo erediterà semplicemente; così possiamo facilmente modificarlo.

1) Utilizzando lo stile in linea :

.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) Utilizzo di CSS e classi

.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) Utilizzo di 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) Utilizzo di 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>


Può essere utilizzato anche con valori complessi:

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

Potresti notare che sto prendendo in considerazione la sintassi var(--c,value) dovevalue trova il valore predefinito e anche chiamato valore di fallback.

Dalla stessa specifica possiamo leggere:

Il valore di una proprietà personalizzata può essere sostituito nel valore di un'altra proprietà con la funzione var (). La sintassi di var () è:

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

Il primo argomento della funzione è il nome della proprietà personalizzata da sostituire. Il secondo argomento della funzione, se fornito, è un valore di fallback, che viene utilizzato come valore di sostituzione quando la proprietà personalizzata a cui viene fatto riferimento non è valida.

E più tardi:

Per sostituire un var () nel valore di una proprietà:

  1. Se la proprietà personalizzata denominata dal primo argomento della var()funzione è contaminata dall'animazione, e il filevar() funzione viene utilizzata nella proprietà di animazione o in uno dei suoi longhands, considera la proprietà personalizzata come avere il suo valore iniziale per il resto di questo algoritmo.
  2. Se il valore della proprietà personalizzata indicata dal primo argomento della var()funzione è tutt'altro che il valore iniziale, sostituire ilvar() funzione con il valore della proprietà personalizzata corrispondente.
  3. Altrimenti, se la var()funzione ha un valore di fallback come secondo argomento, sostituire la var()funzione con il valore di fallback. Se ce ne sonovar() nel fallback riferimenti, sostituirli anche.
  4. In caso contrario, la proprietà contenente la var()funzione non è valida al momento del valore calcolato.

Se non impostiamo la proprietà personalizzata OR la ​​impostiamo su initialOR contiene un valore non valido, verrà utilizzato il valore di fallback. L'uso di initialpuò essere utile nel caso in cui vogliamo ripristinare una proprietà personalizzata al suo valore predefinito.

Relazionato

Come archiviare il valore ereditario all'interno di una proprietà personalizzata CSS (ovvero variabili CSS)?

Proprietà personalizzate CSS (variabili) per il modello box


Tieni presente che le variabili CSS potrebbero non essere disponibili in tutti i browser che ritieni pertinenti (ad esempio IE 11): https://caniuse.com/#feat=css-variables


@akalata sì, il codice richiede una versione 3.x di jQuery. Ho aggiunto maggiori dettagli e un'altra alternativa con jQuery;)
Temani Afif

Come funzionerebbe in IE 11?
connexo,

1
@connexo come qualsiasi funzionalità buona e moderna .. non è supportato e non funzionerà caniuse.com/#feat=css-variables
Afif

Spesso lo sapevo e dato che IE 11 è ancora molto rilevante, ho perso quella informazione proprio nella parte introduttiva della tua risposta.
connexo,

1
Questa risposta è un tutorial approfondito sulla relazione e la modifica di pseudo-elementi con JavaScript mediante variabili CSS. Grazie mille per il tuo tempo e per aver condiviso questa (e) tecnica (e) estremamente preziosa.
LebCit

37

In linea con ciò che Christian suggerisce, potresti anche fare:

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

2
Qui dovrebbe essere aggiunto un attributo id, quindi l'elemento può essere selezionato ed eliminato prima di aggiungerne uno nuovo. Altrimenti, possono nascere molti nodi di stile non necessari.
KS,

24

Ecco il modo di accedere a: after e: before proprietà dello stile, definite in 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

Se si desidera manipolare gli elementi sudo :: before o :: after interamente tramite CSS, è possibile farlo JS. Vedi sotto;

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

Notare come il <style> elemento ha un ID, che puoi usare per rimuoverlo e aggiungerlo di nuovo se il tuo stile cambia dinamicamente.

In questo modo, il tuo elemento è stile esattamente come lo desideri tramite CSS, con l'aiuto di JS.


6

un modo efficace ma non molto efficace è aggiungere una regola al documento con il nuovo contenuto e fare riferimento a esso con una classe. a seconda di ciò che è necessario, la classe potrebbe aver bisogno di un ID univoco per ciascun valore nel contenuto.

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

5

Ecco l'HTML:

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

Lo stile calcolato su "prima" era content: "VERIFY TO WATCH";

Ecco le mie due righe di jQuery, che usano l'idea di aggiungere una classe extra per fare riferimento in modo specifico a questo elemento e quindi aggiungere un tag di stile (con un tag! Important) per modificare il CSS del valore del contenuto dell'elemento sudo:

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

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


5

Grazie a tutti! sono riuscito a fare quello che volevo: D http://jsfiddle.net/Tfc9j/42/ qui dai un'occhiata

volevo che l'opacità di un div esterno fosse diversa dall'opacità del div interno e che cambia con un clic da qualche parte;) Grazie!

   $('#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>

Non provare append, usare htmlè meglio prevenire
KingRider

1
Attenzione: qui stai aggiungendo un tag di stile alla testa ogni volta che uno di questi clic viene gestito. Codificherei un modo per rimuovere quello vecchio prima di aggiungerne uno nuovo.
pupitetris,

3

Puoi creare una proprietà falsa o usarne una esistente ed ereditarla nel foglio di stile dello pseudo-elemento.

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>

Sembra che non funzioni con la proprietà "content" :(


3

Questo non è pratico perché non l'ho scritto per gli usi del mondo reale, solo per darti un esempio di ciò che può essere raggiunto.

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

questo attualmente aggiunge un / o aggiunge un elemento Style che contiene i tuoi attributi necessari che avranno effetto sull'elemento target dopo lo pseudo elemento.

questo può essere usato come

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

e

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

come dopo: e prima: gli pseudo elementi non sono direttamente accessibili tramite DOM, al momento non è possibile modificare liberamente i valori specifici del CSS.

la mia strada era solo un esempio e non è buona per la pratica, puoi modificarla provando alcuni dei tuoi trucchi e renderla corretta per l'uso nel mondo reale.

quindi fai la tua sperimentazione con questo e altri!

saluti - Adarsh ​​Hegde.


3

Aggiungo sempre la mia funzione utils, che assomiglia a questa.

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

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

o utilizzare le funzionalità ES6:

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

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

2

Perché aggiungere classi o attributi quando puoi semplicemente aggiungere un stylea head

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

2

Ci sono molte risposte qui, ma nessuna risposta aiuta a manipolare il CSS :beforeo :after, nemmeno quello accettato.

Ecco come propongo di farlo. Supponiamo che il tuo HTML sia così:

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

E poi lo stai impostando: prima in CSS e progettandolo come:

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

Si noti che ho anche impostato l' contentattributo nell'elemento stesso in modo da poterlo estrarre facilmente in seguito. Ora c'è unbutton clic su cui, vuoi cambiare il colore di: prima in verde e la sua dimensione del carattere a 30px. Puoi farlo come segue:

Definisci un css con il tuo stile richiesto su alcune classi .activeS:

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

Ora puoi cambiare: before style aggiungendo la classe al tuo elemento: before come segue:

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

Se vuoi solo ottenere il contenuto di :before, puoi farlo come:

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

In definitiva, se si desidera modificare dinamicamente i :beforecontenuti di jQuery, è possibile ottenere ciò come segue:

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

Facendo clic sul pulsante "changeBefore" sopra, il :beforecontenuto cambierà #somethingin "22", che è un valore dinamico.

spero possa essere d'aiuto


1

Ho fatto uso delle variabili definite :rootall'interno CSSper modificare lo pseudo-elemento:after (lo stesso vale per :before) , in particolare per cambiare il valore per uno stile definito da e il valore per un altro ( ) nella seguente demo che genera colori casuali utilizzando 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("");
 }
);

Il supporto per attr()tranne in content, è davvero scarso. Puoi controllare caniuse.com per questo. :roote il supporto per variabili css è migliore, ma non è ancora così diffuso poiché il supporto è piuttosto nuovo. (controlla anche il supporto su caniuse.com)
BananaAcid

1

Ho creato un plug-in jQuery per aggiungere regole css-pseudo come l'utilizzo .css()per elementi specifici.

  • codice plug-in e test case è qui
  • usa il caso come semplice popup immagine CSS qui

utilizzo:

$('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

Puoi usare il mio plugin per questo scopo.

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>

I valori devono essere specificati, come nella normale funzione di jQuery.css

Inoltre, puoi anche ottenere il valore del parametro pseudo-elemento, come nella normale funzione di jQuery.css:

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

JS:


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


0

Qualcun altro ha commentato l'aggiunta all'elemento head con un elemento di stile completo e non è male se lo fai solo una volta ma se devi reimpostarlo più di una volta finirai con una tonnellata di elementi di stile. Quindi, per evitare che ho creato un elemento di stile vuoto nella testa con un ID e ho sostituito l'HTML interno di esso in questo modo:

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

Quindi JavaScript sarebbe simile al seguente:

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

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

setHeight()

Ora nel mio caso avevo bisogno di questo per impostare l'altezza di un elemento precedente in base all'altezza di un altro e cambierà al ridimensionamento, quindi usando questo posso eseguire setHeight()ogni volta che la finestra viene ridimensionata e sostituirà <style>correttamente.

Spero che aiuti qualcuno che è rimasto bloccato cercando di fare la stessa cosa.


-1

Ho qualcosa di diverso per te che è facile ed efficace.

    <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');
    });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.