Question Sélection et manipulation de pseudo-éléments CSS tels que :: before et :: after à l'aide de jQuery


Y at-il un moyen 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 puis-je changer 'foo' en 'bar' en utilisant jQuery?


782
2018-02-18 12:53


origine


Réponses:


Vous pouvez également passer le contenu à l'élément pseudo avec un attribut de données, puis utiliser jQuery pour manipuler cela:

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 vous voulez empêcher l'affichage de l'autre texte, vous pouvez le combiner avec la solution de seucolega comme ceci:

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';
}

606
2018-04-20 17:59



Vous penseriez que ce serait une question simple à répondre, avec tout ce que jQuery peut faire. Malheureusement, le problème se résume à un problème technique: css: après et: avant que les règles ne fassent partie du DOM, et ne peut donc pas être modifié en utilisant les méthodes DOM de jQuery.

sont façons de manipuler ces éléments en utilisant des solutions de contournement JavaScript et / ou CSS; celui que vous utilisez dépend de vos besoins exacts.


Je vais commencer par ce qui est généralement 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 autre :after ou :before style. 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 de 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 JS de votre HTML)
  • Les inconvénients: CSS doit être pré-écrit, de sorte que 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 :after et :before modes. 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 connexes .insertRule() méthodes sont assez bien supportés aujourd'hui.

En variante, vous pouvez également utiliser jQuery pour ajouter une feuille de style entièrement nouvelle au document, mais le code nécessaire n'est pas un nettoyeur:

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 seulement en les ajoutant, nous pouvons aussi lis l'existant :after ou :before modes 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') avec $('p')[0] lors de l'utilisation de jQuery, pour un code légèrement plus court.

  • Avantages: n'importe quelle chaîne peut être insérée dynamiquement dans le style
  • Les inconvénients: les styles originaux ne sont pas altérés, simplement remplacés; l'utilisation répétée (ab) peut rendre le DOM grandir arbitrairement grand

3) Modifier un autre attribut DOM

Vous pouvez aussi utilisation attr() dans votre CSS lire un attribut DOM particulier. (Si un navigateur prend en charge :before, Elle supporte attr() ainsi que.) En combinant cela 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 seconde 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
  • Les inconvénients:  attr en CSS ne peut s'appliquer qu'aux chaînes de contenu, pas aux URL ou aux couleurs RVB

391
2018-02-11 18:14



Bien qu'ils soient rendus par les navigateurs via CSS comme s'ils étaient comme les autres éléments DOM réels, les pseudo-éléments eux-mêmes ne font pas partie du DOM, car les pseudo-éléments, comme son nom l'indique, ne sont pas des éléments réels. sélectionnez-les et manipulez-les directement avec jQuery (ou tout API JavaScript d'ailleurs, même pas le API de sélection). Cela 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ée par jQuery au-delà .css(), une méthode qui ne supporte pas non plus les pseudo-éléments.

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

  • Appliquer les styles aux pseudo-éléments d'une ou plusieurs classes arbitraires, puis basculer entre les classes (voir La réponse de seucolega pour un exemple rapide) - c'est la manière idiomatique car elle utilise des sélecteurs simples (ce que les pseudo-éléments ne sont pas) pour faire la distinction entre 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 aux pseudo-éléments, en modifiant la feuille de style du document, qui est beaucoup plus un hack


144
2018-02-18 12:56



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 contrôler ses pseudo-éléments en CSS.

EXEMPLE

En jQuery:

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

En CSS:

span.change:after { content: 'bar' }

72
2018-03-17 06:46



Dans la ligne de ce que Christian suggère, vous pouvez aussi faire:

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

34
2017-10-18 10:20



Voici comment accéder: after et: before propriétés de style, 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');

20
2017-07-15 21:55



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 devrait être Oui Non. Vous ne pouvez pas sélectionner un élément via un pseudo-sélecteur, mais vous pouvez ajouter une nouvelle règle à votre feuille de style avec javascript.

J'ai fait quelque chose qui devrait marcher 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
2018-05-12 12:18



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

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

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

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


11
2018-06-14 20:13



une façon de travailler mais pas très efficace est d'ajouter une règle au document avec le nouveau contenu et de le référencer avec une classe. en fonction de ce qui est nécessaire, 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');

5
2017-09-12 13:27



Voici le code HTML:

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

Le style calculé sur «avant» était content: "VERIFY TO WATCH";

Voici mes deux lignes de jQuery, qui utilisent l'idée d'ajouter une classe supplémentaire pour référencer spécifiquement cet élément et d'ajouter une balise de style (avec une balise! Important) pour modifier le CSS de la valeur du contenu de l'élément sudo:

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

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


5
2018-03-18 23:27



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

je voulais avoir l'opacité d'un div externe pour être différent de l'opacité de la div interne et cela change avec 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
2017-07-10 15:26