Pensarías que esta sería una pregunta simple de responder, con todo lo demás que jQuery puede hacer. Desafortunadamente, el problema se reduce a un problema técnico: css: after y: before las reglas no son parte del DOM y , por lo tanto, no pueden modificarse utilizando los métodos DOM de jQuery.
No son formas de manipular estos elementos utilizando JavaScript y / o CSS soluciones; cuál usa depende de sus requisitos exactos.
Voy a comenzar con lo que se considera ampliamente el "mejor" enfoque:
1) Agregar / eliminar una clase predeterminada
En este enfoque, ya ha creado una clase en su CSS con un estilo :after
o :before
estilo diferente . Coloque esta clase "nueva" más adelante en su hoja de estilo para asegurarse de que anula:
p:before {
content: "foo";
}
p.special:before {
content: "bar";
}
Luego, puede agregar o eliminar fácilmente esta clase utilizando jQuery (o JavaScript de vainilla):
$('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>
- Pros: Fácil de implementar con jQuery; altera rápidamente varios estilos a la vez; impone la separación de preocupaciones (aislando su CSS y JS de su HTML)
- Contras: CSS debe estar preescrito, por lo que el contenido de
:before
o :after
no es completamente dinámico
2) Agregue nuevos estilos directamente a la hoja de estilo del documento
Es posible usar JavaScript para agregar estilos directamente a la hoja de estilo del documento, incluidos los estilos :after
y :before
. jQuery no proporciona un atajo conveniente, pero afortunadamente el JS no es tan 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()
y los .insertRule()
métodos relacionados están bastante bien soportados hoy.
Como variación, también puede usar jQuery para agregar una hoja de estilo completamente nueva al documento, pero el código necesario no es más limpio:
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>
Si estamos hablando de "manipular" los valores, no solo agregarlos, también podemos leer los estilos existentes :after
o:before
usar un enfoque 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 reemplazar document.querySelector('p')
con $('p')[0]
cuando usamos jQuery, para un código ligeramente más corto.
- Pros: cualquier cadena se puede insertar dinámicamente en el estilo
- Contras: los estilos originales no se modifican, solo se anulan; el uso repetido (ab) puede hacer que el DOM crezca arbitrariamente grande
3) Alterar un atributo DOM diferente
También puede usar attr()
en su CSS para leer un atributo DOM particular. ( Si un navegador es compatible :before
, también lo esattr()
) . Al combinar esto con content:
un CSS cuidadosamente preparado, podemos cambiar el contenido (pero no otras propiedades, como el margen o el color) :before
y :after
dinámicamente:
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>
Esto se puede combinar con la segunda técnica si el CSS no se puede preparar con anticipación:
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>
- Pros: no crea infinitos estilos adicionales
- Contras:
attr
en CSS solo se puede aplicar a cadenas de contenido, no a URL o colores RGB