web-dev-qa-db-fra.com

Sélection et manipulation de pseudo-éléments CSS tels que :: before et :: after avec jQuery

Est-il possible de sélectionner/manipuler des pseudo-éléments CSS tels que ::before et ::after (et l'ancienne version avec un point-virgule) à l'aide de jQuery?

Par exemple, ma feuille de style a la règle suivante:

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

Comment puis-je changer 'foo' en 'bar' en utilisant jQuery?

832
JBradwell

Vous pouvez également transmettre le contenu au pseudo-élément avec un attribut de données, puis utiliser jQuery pour manipuler ce qui suit:

En HTML:

<span>foo</span>

Dans jQuery:

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

En CSS: 

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

Si vous souhaitez empêcher "l'autre texte" de s'afficher, vous pouvez combiner ceci avec la solution de seucolega comme ceci:

En HTML:

<span>foo</span>

Dans 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';
}
642
Nick Kline

Vous penseriez que ce serait une question simple à laquelle répondre, avec tout ce que jQuery peut faire. Malheureusement, le problème se résume à un problème technique: css: after et: before les règles ne font pas partie du DOM, et ne peut donc pas être modifié à l'aide des méthodes DOM de jQuery.

Il existe des moyens de manipuler ces éléments à l'aide de solutions de contournement JavaScript et/ou CSS. lequel vous utilisez dépend de vos besoins exacts.


Je vais commencer par ce qui est largement considéré comme la "meilleure" approche:

1) Ajouter/supprimer une classe prédéterminée

Dans cette approche, vous avez déjà créé une classe dans votre CSS avec un style :after ou :before différent. Placez cette "nouvelle" classe plus tard dans votre feuille de style pour vous assurer qu'elle remplace:

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

Ensuite, vous pouvez facilement ajouter ou supprimer cette classe en utilisant jQuery (ou 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>
  • Avantages: Facile à implémenter avec jQuery; modifie rapidement plusieurs styles à la fois; impose la séparation des préoccupations (isoler votre CSS et votre JS de votre HTML)
  • Inconvénients: CSS doit être pré-écrit, le contenu de :before ou :after n'est pas complètement dynamique

2) Ajouter de nouveaux styles directement à la feuille de style du document

Il est possible d’utiliser JavaScript pour ajouter des styles directement à la feuille de style du document, notamment les styles :after et :before. jQuery ne fournit pas un raccourci pratique, mais heureusement, le JS n'est pas si compliqué:

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() et les méthodes .insertRule() associées sont assez bien supportés aujourd'hui.

En variante, vous pouvez également utiliser jQuery pour ajouter une nouvelle feuille de style au document, mais le code nécessaire n’est pas plus propre:

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 nous parlons de "manipuler" les valeurs, pas simplement d’y ajouter, nous pouvons aussi lire les styles :after ou :before existants en utilisant un autre approche:

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>

Nous pouvons remplacer document.querySelector('p') par $('p')[0] lors de l'utilisation de jQuery, pour un code légèrement plus court.

  • Avantages: toute chaîne peut être insérée dynamiquement dans le style
  • Inconvénients: les styles d'origine ne sont pas modifiés, mais simplement remplacés; une utilisation répétée (ab) peut rendre le DOM grossir arbitrairement

3) Modifier un attribut DOM différent

Vous pouvez également tiliser attr() dans votre CSS pour lire un attribut DOM particulier. ( Si un navigateur supporte :before, il supporte aussi attr(). ) En combinant ceci avec content: dans certains CSS soigneusement préparés, nous pouvons changer le contenu (mais pas d'autres propriétés, comme la marge ou la couleur) de :before et :after dynamiquement:

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>

Ceci peut être combiné avec la deuxième technique si le CSS ne peut pas être préparé à l'avance:

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>
  • Avantages: Ne crée pas de styles supplémentaires sans fin
  • Inconvénients: attr en CSS ne peut s'appliquer qu'aux chaînes de contenu, pas aux URL ni aux couleurs RVB
443
Blazemonger

Bien qu'ils soient rendus par les navigateurs via CSS comme s'ils ressemblaient à d'autres éléments réels du DOM, les pseudo-éléments eux-mêmes ne font pas partie du DOM, car les pseudo-éléments, comme leur nom l'indique, ne sont pas de vrais éléments. sélectionnez-les et manipulez-les directement avec jQuery (ou les API JavaScript any d'ailleurs, pas même l'API Selectors ). Cela s'applique à tous les pseudo-éléments dont vous essayez de modifier les styles à l'aide d'un script, et pas seulement ::before et ::after.

Vous pouvez uniquement accéder aux styles de pseudo-éléments directement au moment de l'exécution via le CSSOM (think window.getComputedStyle()), qui n'est pas exposé par jQuery au-delà de .css(), une méthode ne prenant pas non plus en charge les pseudo-éléments.

Vous pouvez toujours trouver d'autres moyens de contourner le problème, par exemple:

  • Appliquer les styles aux pseudo-éléments d’une ou de plusieurs classes arbitraires, puis basculer entre les classes (voir réponse de seucolega pour un exemple rapide) - c’est la façon idiomatique d’utiliser des sélecteurs simples (pseudo-éléments ne sont pas) pour distinguer les éléments et les états des éléments, la façon dont ils sont destinés à être utilisés

  • Manipuler les styles appliqués auxdits pseudo-éléments, en modifiant la feuille de style du document, ce qui est beaucoup plus un hack

152
BoltClock

Vous ne pouvez pas sélectionner de pseudo-éléments dans jQuery car ils ne font pas partie de DOM . Mais vous pouvez ajouter une classe spécifique à l'élément père et en contrôler les pseudo-éléments en CSS.

EXEMPLE

Dans jQuery:

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

En CSS:

span.change:after { content: 'bar' }
75
Gustavo Sousa

Dans le sens de ce que suggère Christian, vous pourriez aussi faire:

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

Voici le moyen d'accéder aux propriétés de style after et: before, définies dans 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');
23
Nedudi

Nous pouvons également compter sur propriétés personnalisées (variables CSS) } pour manipuler un pseudo-élément. On peut lire dans la spécification que:

Les propriétés personnalisées sont des propriétés ordinaires, elles peuvent donc être déclarées sur tous les éléments, sont résolus avec les héritages normal et cascaderules, peut être conditionné avec @media et d’autres règles conditionnelles, peut être utilisé dans l’attribut de style HTML, peut être read ou défini à l’aide de CSSOM, etc.

Compte tenu de cela, l’idée est de définir la propriété personnalisée dans l’élément et le pseudo-élément l’héritera simplement; ainsi nous pouvons facilement le modifier.

Veuillez noter que les variables CSS peuvent ne pas être disponibles dans tous les navigateurs que vous considérez comme pertinents (par exemple IE 11): https://caniuse.com/#feat=css-variables

1) Utilisation du style en ligne:

.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}
<div class="box"></div>
<div class="box" style="--color:blue"></div>
<div class="box" style="--color:black"></div>
<div class="box" style="--color:#f0f"></div>

2) Utilisation de CSS et des classes

.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}

.blue {
  --color:blue;
}
.black {
  --color:black;
}
<div class="box"></div>
<div class="box black" ></div>
<div class="box blue"></div>

3) Utilisation de javascript

document.querySelectorAll('.box')[0].style.setProperty("--color", "blue");
document.querySelectorAll('.box')[1].style.setProperty("--color", "#f0f");
.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>

4) Utilisation de 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>


Il peut également être utilisé avec des valeurs complexes:

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

20
Temani Afif

SI vous voulez manipuler les éléments :: before ou :: after entièrement par CSS, vous pouvez le faire JS. Voir ci-dessous;

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

Notez que l'élément <style> a un ID que vous pouvez utiliser pour le supprimer et le rajouter si votre style change de manière dynamique.

De cette façon, votre élément est stylé exactement comme vous le souhaitez via CSS, avec l’aide de JS.

11
user595349

Merci à tous! J'ai réussi à faire ce que je voulais: D http://jsfiddle.net/Tfc9j/42/ Voici un aperçu

je voulais que l'opacité d'une div externe soit différente de l'opacité de la div interne et que cela change d'un clic quelque part;) Merci!

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

une méthode efficace mais peu efficace consiste à ajouter une règle au document avec le nouveau contenu et à la référencer avec une classe. En fonction des besoins, la classe peut avoir besoin d'un identifiant unique pour chaque valeur du contenu.

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

Ce n'est pas pratique car je ne l'ai pas écrit pour des utilisations dans le monde réel, juste pour vous donner un exemple de ce qui peut être réalisé. 

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

ceci ajoute actuellement un/un élément de style qui contient vos attributs nécessaires qui auront une incidence sur le pseudo-élément de l'élément cible.

cela peut être utilisé comme 

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

et 

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

comme après: et avant: les pseudo-éléments ne sont pas directement accessibles via DOM, il est actuellement impossible de modifier librement les valeurs spécifiques du fichier css.

mon chemin n’était qu’un exemple et ce n’est pas bon pour la pratique, vous pouvez le modifier, essayer certains de vos propres astuces et les adapter à une utilisation réelle.

alors faites votre propre expérimentation avec ceci et d'autres!

cordialement - Adarsh ​​Hegde. 

3
Adarsh Hegde

Pourquoi ajouter des classes ou des attributs quand vous pouvez simplement ajouter une style à head

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

Vous pouvez créer une fausse propriété ou utiliser une propriété existante et inherit it dans la feuille de style du pseudo-élément.

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>

Il semble que cela ne fonctionne pas pour la propriété "content" :(

2
Alexander Shutov

Il y a beaucoup de réponses ici mais aucune réponse ne permet de manipuler le css de :before ou :after, pas même celui accepté.

Voici comment je propose de le faire. Supposons que votre code HTML ressemble à ceci:

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

Et ensuite, vous définissez son: before dans CSS et vous le concevez comme suit:

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

Veuillez noter que je mets également l'attribut content dans l'élément lui-même afin de pouvoir le supprimer facilement plus tard . Il existe maintenant un clic sur button sur lequel vous souhaitez modifier la couleur de: before en vert et sa taille de police à 30px . Vous pouvez y parvenir comme suit:

Définissez un css avec le style requis sur une classe .activeS:

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

Vous pouvez maintenant modifier: before avant en ajoutant la classe à votre élément: before comme suit:

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

Si vous voulez juste obtenir le contenu de :before, vous pouvez le faire comme suit:

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

En fin de compte, si vous souhaitez modifier dynamiquement le contenu de :before par jQuery, procédez comme suit:

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

En cliquant sur le bouton "changeBefore" ci-dessus, le contenu de :before de #something sera remplacé par "22", ce qui est une valeur dynamique.

J'espère que ça aide

1
Learner

J'ajoute toujours ma propre fonction utils, qui ressemble à ceci.

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

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

ou utilisez les fonctionnalités de l'ES6:

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

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

J'ai créé un plugin jQuery pour ajouter des règles css-pseudo telles que l'utilisation de .css() pour des éléments spécifiques.

  • le code du plugin et le cas de test est ici
  • cas d'utilisation comme simple image css popup ici

usage:

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

Vous pouvez utiliser mon plugin à cet effet.

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>

Les valeurs doivent être spécifiées, comme dans la fonction normale de jQuery.css

De plus, vous pouvez également obtenir la valeur du paramètre pseudo-élément, comme dans la fonction normale de jQuery.css:

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

JS:

(function() {
  document.pseudoElements = {
    length: 0
  };

  var setPseudoElement = function(parameters) {
    if (typeof parameters.argument === 'object' || (parameters.argument !== undefined && parameters.property !== undefined)) {
      if (!parameters.element.pseudoElements) parameters.element.pseudoElements = {
        styleSheet: null,
        before: {
          index: null,
          properties: null
        },
        after: {
          index: null,
          properties: null
        },
        id: null
      };

      var selector = (function() {
        if (parameters.element.pseudoElements.id !== null) {
          if (Number(parameters.element.getAttribute('data-pe--id')) !== parameters.element.pseudoElements.id) parameters.element.setAttribute('data-pe--id', parameters.element.pseudoElements.id);
          return '[data-pe--id="' + parameters.element.pseudoElements.id + '"]::' + parameters.pseudoElement;
        } else {
          var id = document.pseudoElements.length;
          document.pseudoElements.length++

            parameters.element.pseudoElements.id = id;
          parameters.element.setAttribute('data-pe--id', id);

          return '[data-pe--id="' + id + '"]::' + parameters.pseudoElement;
        };
      })();

      if (!parameters.element.pseudoElements.styleSheet) {
        if (document.styleSheets[0]) {
          parameters.element.pseudoElements.styleSheet = document.styleSheets[0];
        } else {
          var styleSheet = document.createElement('style');

          document.head.appendChild(styleSheet);
          parameters.element.pseudoElements.styleSheet = styleSheet.sheet;
        };
      };

      if (parameters.element.pseudoElements[parameters.pseudoElement].properties && parameters.element.pseudoElements[parameters.pseudoElement].index) {
        parameters.element.pseudoElements.styleSheet.deleteRule(parameters.element.pseudoElements[parameters.pseudoElement].index);
      };

      if (typeof parameters.argument === 'object') {
        parameters.argument = (function() {
          var cloneObject = typeof parameters.argument.pop === 'function' ? [] : {};

          for (var property in parameters.argument) {
            cloneObject[property] = parameters.argument[property];
          };

          return cloneObject;
        })();

        if (!parameters.element.pseudoElements[parameters.pseudoElement].properties && !parameters.element.pseudoElements[parameters.pseudoElement].index) {
          var newIndex = parameters.element.pseudoElements.styleSheet.rules.length || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length;

          parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex;
          parameters.element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;
        };

        var properties = '';

        for (var property in parameters.argument) {
          if (typeof parameters.argument[property] === 'function')
            parameters.element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();
          else
            parameters.element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];
        };

        for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) {
          properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
        };

        parameters.element.pseudoElements.styleSheet.addRule(selector, properties, parameters.element.pseudoElements[parameters.pseudoElement].index);
      } else if (parameters.argument !== undefined && parameters.property !== undefined) {
        if (!parameters.element.pseudoElements[parameters.pseudoElement].properties && !parameters.element.pseudoElements[parameters.pseudoElement].index) {
          var newIndex = parameters.element.pseudoElements.styleSheet.rules.length || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length;

          parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex;
          parameters.element.pseudoElements[parameters.pseudoElement].properties = {};
        };

        if (typeof parameters.property === 'function')
          parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property();
        else
          parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property;

        var properties = '';

        for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) {
          properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
        };

        parameters.element.pseudoElements.styleSheet.addRule(selector, properties, parameters.element.pseudoElements[parameters.pseudoElement].index);
      };
    } else if (parameters.argument !== undefined && parameters.property === undefined) {
      var windowStyle = window.getComputedStyle(
        parameters.element, '::' + parameters.pseudoElement
      ).getPropertyValue(parameters.argument);

      if (parameters.element.pseudoElements) {
        return parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] || windowStyle;
      } else {
        return windowStyle || null;
      };
    } else {
      console.error('Invalid values!');
      return false;
    };
  };

  Object.defineProperty(Element.prototype, 'styleBefore', {
    enumerable: false,
    value: function(argument, property) {
      return setPseudoElement({
        element: this,
        pseudoElement: 'before',
        argument: argument,
        property: property
      });
    }
  });
  Object.defineProperty(Element.prototype, 'styleAfter', {
    enumerable: false,
    value: function(argument, property) {
      return setPseudoElement({
        element: this,
        pseudoElement: 'after',
        argument: argument,
        property: property
      });
    }
  });
})();

document.querySelector('.element').styleBefore('content', '"New before!"');
.element {
  width: 480px;
  margin: 0 auto;
  border: 2px solid red;
}

.element::before {
  content: 'Old before!';
}
<div class="element"></div>


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

0
Yuri

 $('.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
Tariq Javed

Quelqu'un a commenté l'ajout à l'élément head avec un élément de style complet et ce n'est pas grave si vous ne le faites qu'une fois, mais si vous devez le réinitialiser plusieurs fois, vous vous retrouverez avec une tonne d'éléments de style. Donc, pour éviter que je crée un élément de style vide dans la tête avec un identifiant et remplacez le innerHTML de celui-ci comme ceci:

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

Alors le JavaScript ressemblerait à ceci: 

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

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

setHeight()

Dans mon cas, j’avais besoin de cela pour définir la hauteur d’un élément before en fonction de la hauteur d’un autre élément. Elle changera en fonction du redimensionnement. Ainsi, je peux exécuter setHeight() chaque fois que la fenêtre est redimensionnée et elle remplacera le <style> correctement.

J'espère que cela aidera quelqu'un qui était coincé à essayer de faire la même chose.

0
zfb

J'ai utilisé les variables définies dans :root inside CSS pour modifier le :after (il en va de même pour :before) pseudo-élément, en particulier pour modifier la valeur background-color d'un anchor stylé défini par .sliding-middle-out:hover:after et la valeur content pour une autre anchor (#reference) dans la démo suivante qui génère des couleurs aléatoires à l'aide de JavaScript/jQuery:

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("");
 }
);
0
Riccardo Volpe