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 :after
o :before
stile. 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');
});
$('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>
- 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
:before
o :after
non è 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 :after
e :before
stili. 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+'";');
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()
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');
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>
Se stiamo parlando di "manipolare" i valori, non solo di aggiungerli, possiamo anche leggere gli stili esistenti :after
o:before
usando un approccio diverso:
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>
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) :before
e :after
dinamicamente:
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>
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);
});
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>
- 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