Você acha que essa seria uma pergunta simples de responder, com tudo o mais que o jQuery pode fazer. Infelizmente, o problema se resume a um problema técnico: regras de css: after e: before não fazem parte do DOM e , portanto, não podem ser alteradas usando os métodos DOM do jQuery.
Não são maneiras de manipular esses elementos usando JavaScript e / ou CSS soluções alternativas; qual você usa depende de seus requisitos exatos.
Vou começar com o que é amplamente considerado a "melhor" abordagem:
1) Adicionar / remover uma classe predeterminada
Nesta abordagem, você já criou uma classe em seu CSS com um estilo :after
ou :before
estilo diferente . Posicione essa classe "nova" posteriormente na folha de estilo para garantir que ela substitua:
p:before {
content: "foo";
}
p.special:before {
content: "bar";
}
Em seguida, você pode adicionar ou remover facilmente essa classe usando jQuery (ou vanilla JavaScript):
$('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>
- Prós: Fácil de implementar com jQuery; altera rapidamente vários estilos ao mesmo tempo; impõe a separação de preocupações (isolando seu CSS e JS do seu HTML)
- Contras: o CSS deve ser pré-escrito, para que o conteúdo
:before
ou :after
não seja completamente dinâmico
2) Adicione novos estilos diretamente à folha de estilo do documento
É possível usar o JavaScript para adicionar estilos diretamente à folha de estilo do documento, incluindo :after
e :before
estilos. O jQuery não fornece um atalho conveniente, mas felizmente o JS não é tão complicado:
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 os .insertRule()
métodos relacionados são razoavelmente bem suportados hoje.
Como variação, você também pode usar o jQuery para adicionar uma folha de estilo totalmente nova ao documento, mas o código necessário não é mais limpo:
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 estamos falando de "manipular" os valores, não apenas acrescentar a eles, podemos também ler os existentes :after
ou :before
estilos que utilizam uma abordagem diferente:
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>
Podemos substituir document.querySelector('p')
com $('p')[0]
ao usar jQuery, para o código ligeiramente mais curto.
- Prós: qualquer string pode ser inserida dinamicamente no estilo
- Contras: os estilos originais não são alterados, apenas substituídos; O uso repetido (ab) pode fazer o DOM crescer arbitrariamente grande
3) Alterar um atributo DOM diferente
Você também pode usar attr()
em seu CSS para ler um atributo DOM específico. ( Se um navegador suporta :before
, ele também suporta attr()
. ) Ao combinar isso com content:
algumas CSS cuidadosamente preparadas, podemos alterar o conteúdo (mas não outras propriedades, como margem ou cor) :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>
Isso pode ser combinado com a segunda técnica se o CSS não puder ser preparado com antecedência:
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>
- Prós: Não cria infinitos estilos extras
- Contras:
attr
no CSS, só se aplica a cadeias de conteúdo, não a URLs ou cores RGB