Seleccionar y manipular pseudoelementos CSS como ::before y ::after usando javascript (o jQuery)

Resuelto JBradwell asked hace 13 años • 28 respuestas

¿Hay alguna forma de seleccionar/manipular pseudoelementos CSS como ::beforey ::after(y la versión anterior con un punto y coma) usando jQuery?

Por ejemplo, mi hoja de estilo tiene la siguiente regla:

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

¿Cómo puedo cambiar 'foo' a 'bar' usando Vanilla JS o jQuery?

JBradwell avatar Feb 18 '11 19:02 JBradwell
Aceptado

También puedes pasar el contenido al pseudo elemento con un atributo de datos y luego usar jQuery para manipularlo:

En HTML:

<span>foo</span>

En jQuery:

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

En CSS:

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

Si desea evitar que aparezca el "otro texto", puede combinarlo con la solución de seucolega como esta:

En HTML:

<span>foo</span>

En jQuery:

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

En CSS:

span.change:after {
    content: attr(data-content) ' any other text you may want';
}
Nick Kline avatar Apr 20 '2011 17:04 Nick Kline

Uno pensaría que esta sería una pregunta sencilla de responder, con todo lo demás que jQuery puede hacer. Desafortunadamente, el problema se reduce a una cuestión técnica: las reglas css :after y :before no son parte del DOM y, por lo tanto, no se pueden modificar utilizando los métodos DOM de jQuery.

Hay formas de manipular estos elementos utilizando soluciones alternativas de JavaScript y/o CSS; cuál utilice depende de sus requisitos exactos.


Voy a empezar con lo que se considera ampliamente el "mejor" enfoque:

1) Agregar/eliminar una clase predeterminada

En este enfoque, ya has creado una clase en tu CSS con un :afterestilo diferente :before. Coloque esta clase "nueva" más adelante en su hoja de estilo para asegurarse de que anule:

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

Luego puedes agregar o eliminar fácilmente esta clase usando jQuery (o JavaScript básico):

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

Mostrar fragmento de código

  • Ventajas: 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)
  • Desventajas: CSS debe estar escrito previamente, por lo que el contenido :beforeno :afteres completamente dinámico

2) Agregue nuevos estilos directamente a la hoja de estilos del documento.

Es posible utilizar JavaScript para agregar estilos directamente a la hoja de estilos del documento, incluidos los estilos :aftery :before. jQuery no proporciona un atajo conveniente, pero afortunadamente JS no es tan complicado:

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

Mostrar fragmento de código

.addRule()y los .insertRule()métodos relacionados están bastante bien respaldados en la actualidad.

Como variación, también puedes 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');

Mostrar fragmento de código

Si estamos hablando de "manipular" los valores, no solo agregarlos, también podemos leer los estilos existentes :afterusando un :beforeenfoque diferente:

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

Mostrar fragmento de código

Podemos reemplazarlo document.querySelector('p')con $('p')[0]cuando usemos jQuery, para obtener un código un poco más corto.

  • Ventajas: cualquier cadena se puede insertar dinámicamente en el estilo.
  • Desventajas: los estilos originales no se modifican, sólo se anulan; El (ab)uso repetido puede hacer que el DOM crezca arbitrariamente.

3) Modificar un atributo DOM diferente

También puedes usarlo attr()en tu CSS para leer un atributo DOM particular. ( Si un navegador admite , también :beforelo admiteattr() ). Al combinar esto con content:algún CSS cuidadosamente preparado, podemos cambiar el contenido (pero no otras propiedades, como el margen o el color) de :beforey :afterdinámicamente:

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

JS:

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

Mostrar fragmento de código

Esto se puede combinar con la segunda técnica si el CSS no se puede preparar con antelación:

var str = "bar";

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

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

Mostrar fragmento de código

  • Ventajas: No crea infinitos estilos adicionales
  • Contras: attr en CSS solo se puede aplicar a cadenas de contenido, no a URL ni colores RGB
Blazemonger avatar Feb 11 '2014 18:02 Blazemonger