Sélection et manipulation de pseudo-éléments CSS tels que: avant et:après utilisation de 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) en utilisant jQuery?

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

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

Comment changer " foo " en " bar " en utilisant jQuery?

795
demandé sur BoltClock 2011-02-18 15:53:10

21 réponses

vous pouvez également passer le contenu à l'élément pseudo avec un attribut de données et ensuite utiliser jQuery pour manipuler que:

en HTML:

<span>foo</span>

En jQuery:

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

dans CSS:

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

si vous voulez empêcher l' "autre texte" d'apparaître, vous pouvez combiner cela avec la solution de seucolega comme ceci:

en HTML:

<span>foo</span>

En jQuery:

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

dans CSS:

span.change:after {
    content: attr(data-content) ' any other text you may want';
}
620
répondu Nick Kline 2015-09-28 15:11:58

on pourrait penser que ce serait une question simple à répondre, avec tout ce que jQuery peut faire d'autre. Malheureusement, le problème vient à une question technique: css :après et :avant les règles ne font pas partie de la DOM, et donc ne peut pas être modifié en utilisant les méthodes DOM de jQuery.

il sont des façons de manipuler ces éléments en utilisant JavaScript et / ou CSS workarounds; 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 différent :after ou :before . Placez cette classe" Nouvelle "plus tard dans votre feuille de style pour vous assurer qu'elle l'emporte:

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

alors vous pouvez facilement ajouter ou supprimer cette classe en utilisant jQuery (ou JavaScript vanille):

$('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: facile à mettre en œuvre avec jQuery; modifie rapidement plusieurs styles à la fois; renforce la séparation des préoccupations (isoler votre CSS et JS de votre HTML)
  • Inconvénients: CSS doivent être rédigés à l'avance, de sorte que le contenu de :before ou :after n'est pas totalement dynamique

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

il est possible d'utiliser JavaScript pour ajouter des styles directement à la feuille de style du document, y compris 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 .insertRule() méthodes sont assez bien supportés aujourd'hui.

comme 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 on parle de "manipuler" les valeurs, pas simplement les ajouter, Nous pouvons aussi lire l'existant :after ou :before styles en utilisant une approche différente:

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] en utilisant jQuery, pour un code légèrement plus court.

  • Pros: toute corde peut être dynamiquement insérée dans le style
  • Cons: les styles d'origine ne sont pas modifiés, juste dépassés; l'utilisation répétée (ab)peut faire croître le DOM de façon arbitraire

3) Modifier un attribut DOM différent

vous pouvez également à utiliser attr() dans votre CSS pour lire un DOM particulier attribut. ( si un navigateur prend en charge :before , il prend en charge attr() ainsi. ) 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>

cela 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>
  • Pour: Ne pas créer d'infinies d'autres styles
  • Cons: attr dans CSS peut s'appliquer uniquement aux chaînes de contenu, pas les URLs ou les couleurs RGB
399
répondu Blazemonger 2015-06-17 13:38:15

bien qu'ils soient rendus par les navigateurs à travers CSS comme s'ils étaient comme d'autres éléments DOM réels, les pseudo-éléments eux-mêmes ne font pas partie du DOM, parce que les pseudo-éléments, comme leur nom l'indique, ne sont pas des éléments réels, et donc vous ne pouvez pas les sélectionner et les manipuler directement avec jQuery (ou n'importe quel" APIs 151960920 "JavaScript d'ailleurs, pas même le API de sélecteurs ). Ceci s'applique à tous les pseudo-éléments dont vous essayez de modifier les styles. avec un script, et pas seulement ::before et ::after .

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

vous pouvez toujours trouver d'autres moyens de l'contourner, par exemple:

  • appliquer les styles aux pseudo-éléments d'un ou plusieurs les classes arbitraires, puis basculer entre les classes (voir réponse de seucolega pour un exemple rapide) - c'est la façon idiomatique car il fait usage de sélecteurs simples (qui pseudo-éléments ne sont pas) pour distinguer entre les éléments et les États d'élément, la façon dont ils sont destinés à être utilisés

  • manipulation des styles appliqués à ces pseudo-éléments, en modifiant la feuille de style du document, ce qui est beaucoup plus un piratage

148
répondu BoltClock 2018-06-05 02:37:45

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

exemple

En jQuery:

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

dans CSS:

span.change:after { content: 'bar' }
74
répondu Gustavo Sousa 2014-11-19 22:13:50

dans la lignée de ce que suggère Christian, vous pourriez aussi faire:

$('head').append("<style>.span::after{ content:'bar' }</style>");
35
répondu Ivan Chaer 2012-10-18 10:20:22

Voici la façon d'accéder: après et: avant les propriétés de style, défini 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');
21
répondu Nedudi 2014-07-15 21:55:01

j'ai répondu à cette question ici déjà, mais pour être super cool je vais me répéter pour vous.

La réponse doit être Oui Et Non . Vous ne pouvez pas sélectionner un élément via pseudo-sélecteur, mais vous pouvez ajouter une nouvelle règle à votre feuille de style avec javascript.

j'ai fait quelque chose qui devrait fonctionner pour vous:

var addRule = function(sheet, selector, styles) {
    if (sheet.insertRule) return sheet.insertRule(selector + " {" + styles + "}", sheet.cssRules.length);
    if (sheet.addRule) return sheet.addRule(selector, styles);
};

addRule(document.styleSheets[0], "body:after", "content: 'foo'");

http://fiddle.jshell.net/MDyxg/1/

12
répondu yckart 2017-05-23 12:18:25

si vous voulez manipuler les éléments ::avant ou ::après sudo 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>');

remarquez comment l'élément <style> a un ID, que vous pouvez utiliser pour le supprimer et l'ajouter à nouveau si votre style change dynamiquement.

de cette façon, votre élément est style exactement comment vous le voulez à travers CSS, avec l'aide de JS.

11
répondu 2014-06-14 20:13:28

nous pouvons également compter sur css custom properties (variables) afin de manipuler le pseudo-élément. Nous pouvons lire dans la spécification que:

propriétés Personnalisées sont des propriétés ordinaires, de sorte qu'ils peuvent être déclarés sur tout élément, sont résolus avec le héritage normal et cascade règles , peut être fait conditionnel avec @media et d'autres règles conditionnelles, peut être utilisé dans attribut de style de HTML , peut être lu ou défini en utilisant le CSSOM , etc.

en considérant ceci, l'idée est de définir la propriété personnalisée à l'intérieur de l'élément et le pseudo-élément va tout simplement en hériter; ainsi nous pouvons facilement le modifier.

veuillez noter que les variables CSS peuvent ne pas être disponibles dans toutes les catégories. navigateurs que vous jugez pertinents (p. ex. IE 11): https://caniuse.com/#feat=css-variables

1) utilisant le style inline :

.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) utilisant CSS et 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) en utilisant 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) utilisant 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>
7
répondu Temani Afif 2018-09-06 21:35:02

voici le HTML:

<div class="icon">
  <span class="play">
    ::before
  </span>
</div>

Calculé style "d'avant" était content: "VERIFY TO WATCH";

Voici mes deux lignes de jQuery, qui utilisent l'idée d'ajouter une classe supplémentaire pour faire spécifiquement référence à cet élément et ensuite ajouter une étiquette de style (avec un !important tag) pour modifier la valeur CSS du contenu de l'élément sudo:

$("span.play:eq(0)").addClass('G');

$('body').append("<style>.G:before{content:'NewText' !important}</style>");

5
répondu Coyote 2014-03-18 23:27:20

un travail, mais pas très efficace est d'ajouter une règle pour le document avec le nouveau contenu et de référence avec une classe. en fonction de ce qui est nécessaire, la classe peut avoir besoin d'un id unique pour chaque valeur dans le contenu.

$("<style type='text/css'>span.id-after:after{content:bar;}</style>").appendTo($("head"));
$('span').addClass('id-after');
4
répondu Christian 2012-09-12 13:27:47

merci à tous! j'ai réussi à faire ce que je voulais :D http://jsfiddle.net/Tfc9j/42 / voici jeter un oeil

je voulais avoir l'opacité d'une div externe pour être différente de l'opacité de la div interne et ce changement avec un clic somwewhere ;) 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
répondu aimiliano 2014-07-10 15:26:38

ce n'est pas pratique car je n'ai pas écrit ceci pour des utilisations réelles, 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 a / ou ajoute un élément Style qui contient vos attributs nécessaires qui vont affecter l'élément cible après le Pseudo-élément.

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 par DOM il n'est actuellement pas possible d'éditer librement les valeurs spécifiques du css.

mon chemin était juste un exemple et ce n'est pas bon pour la pratique, vous pouvez le modifier essayer quelques-uns de vos propres trucs et le faire corriger pour l'usage du monde réel.

alors faites vos propres expériences avec ceci et d'autres!

regards-Adarsh Hegde.

3
répondu Adarsh Hegde 2015-04-20 11:59:54

vous pouvez créer un faux bien ou utiliser un existant et hériter il 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
répondu Alexander Shutov 2014-10-13 13:57:21

pourquoi ajouter des classes ou des attributs quand vous pouvez simplement ajouter un style à la tête

$('head').append('<style>.span:after{ content:'changed content' }</style>')
2
répondu Gaurav Aggarwal 2016-08-09 06:10:58

il y a beaucoup de réponses ici , mais aucune n'aide à manipuler la css de :before ou :after , même pas celle acceptée.

Voici comment je propose de le faire. Supposons que votre HTML soit comme ceci:

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

et puis vous mettez son: avant dans CSS et de le concevoir comme:

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

s'il vous plaît noter que j'ai aussi défini l'attribut content dans l'élément lui-même afin que vous puissiez l'enlever facilement plus tard. Maintenant il y a un clic button sur lequel, vous voulez changer la couleur de :avant au vert et sa taille de police à 30px. Vous pouvez y parvenir comme suit:

définir un css avec votre style requis sur une certaine classe .activeS :

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

maintenant vous pouvez changer :avant le style en ajoutant la classe à votre: avant l'élément comme suit:

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

si vous voulez juste obtenir le contenu de :before , il peut être fait comme:

<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 voulez changer dynamiquement le contenu :before par jQuery, vous pouvez y parvenir 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, vous changerez :before contenu de #something en " 22 " qui est une valeur dynamique.

j'espère que cela aide

1
répondu Learner 2016-11-14 13:52:26

j'ajoute toujours ma propre fonction utils, qui ressemble à ça.

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

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

ou utiliser les caractéristiques ES6:

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

setPseudoElContent('.class::after', 'Hello World!');
1
répondu Orlandster 2018-09-13 09:56:03

 $('.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
répondu Tariq Javed 2017-06-28 11:42:19

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
répondu Yuri 2017-08-05 11:48:01

Quelqu'un d'autre a commenté l'ajout à l'élément tête avec un élément plein style et ce n'est pas mal si vous ne le faites qu'une fois, mais si vous avez besoin de le réinitialiser plus d'une fois, vous finirez avec une tonne d'éléments de style. Donc pour empêcher que j'ai créé un élément de style vide dans la tête avec un id et remplacer l'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()

maintenant dans mon cas j'ai eu besoin cela permet de définir la hauteur d'un élément before en fonction de la hauteur d'un autre et il va changer sur Redimensionner de sorte qu'en utilisant ceci je peux lancer setHeight() chaque fois que la fenêtre est redimensionnée et il remplacera le <style> correctement.

Espère que ça aide quelqu'un qui a été coincé à essayer de faire la même chose.

0
répondu zfb 2017-09-22 11:01:51

j'ai utilisé des variables définies dans :root inside CSS pour modifier le :after (la même chose s'applique à :before ) pseudo-élément , en particulier pour changer la valeur background-color pour un stylé anchor défini par .sliding-middle-out:hover:after et la valeur content pour un autre anchor ( #reference ) dans le suivant Démo qui génère des couleurs aléatoires en utilisant 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
répondu Riccardo Volpe 2018-09-17 16:19:24