Выбор и управление псевдоэлементами CSS, такими как :: before и :: после использования jQuery

943

Есть ли способ выбрать / манипулировать псевдоэлементами CSS, такими как ::beforeи ::after(и старая версия с одной точкой с запятой), используя jQuery?

Например, моя таблица стилей имеет следующее правило:

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

Как я могу изменить 'foo' на 'bar', используя jQuery?

JBradwell
источник
4
Я сделал что-то, что должно работать для вас: gist.github.com/yckart/5563717
yckart
1
Я ненавижу такие комментарии к stackoverflow, которые я собираюсь написать (где комментатор спрашивает, почему бы вам не сделать это каким-то совершенно противоположным способом? ), Но: в какой-то момент нужно понять проблему разработки кода и заменить этот псевдоэлемент на пролет или что-то. Я думаю, вы знаете, на что я указываю.
zsitro
1
Принятый ответ отличный. Хотя, если вы пытаетесь достичь какого-либо из следующих пунктов, ответ не сработает: 1. изменить стиль: before с помощью JS. 2. изменить содержание: раньше JS Пожалуйста, смотрите мой ответ для этого, если вам это нужно.
Учащийся
@Learner Теперь есть ответ tfor все из них: stackoverflow.com/a/49618941/8620333
Феманитян Afif

Ответы:

695

Вы также можете передать содержимое в псевдоэлемент с атрибутом данных, а затем использовать jQuery для управления этим:

В HTML:

<span>foo</span>

В jQuery:

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

В CSS:

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

Если вы хотите предотвратить отображение «другого текста», вы можете объединить это с решением seucolega, например:

В HTML:

<span>foo</span>

В jQuery:

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

В CSS:

span.change:after {
    content: attr(data-content) ' any other text you may want';
}
Ник Клайн
источник
2
У вас есть ссылка в спецификации для использования этой attrфункции против contentсвойства? Я удивлен, что никогда не слышал об этом ...
Кевин Пено
95
+1 attr(), очень жаль, что я не смог использовать его с другими свойствами, чем content. Демо
Максим Ви.
28
Это связано с тем, что ни один из существующих браузеров не реализован attr()за пределами CSS2, тогда как в самом CSS2 attr()он был определен только для этого contentсвойства.
BoltClock
10
Обновлена ​​ссылка для ссылок на атрибуты: w3.org/TR/css3-values/#attr-notation
477

Вы могли бы подумать, что это будет простой вопрос, со всем остальным, что может сделать jQuery. К сожалению, проблема сводится к технической проблеме: css: after и: before правила не являются частью DOM и поэтому не могут быть изменены с использованием методов DOM jQuery.

Там являются способы манипулировать эти элементы , используя JavaScript и / или CSS обходные пути; какой из них вы используете, зависит от ваших конкретных требований.


Я собираюсь начать с того, что широко считается «лучшим» подходом:

1) Добавить / удалить заранее определенный класс

При таком подходе вы уже создали класс в своем CSS с другим :afterили :beforeстилем. Поместите этот «новый» класс позже в таблицу стилей, чтобы убедиться, что он переопределяет:

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

Затем вы можете легко добавить или удалить этот класс, используя jQuery (или ванильный JavaScript):

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

  • Плюсы: легко реализовать с помощью jQuery; быстро меняет несколько стилей одновременно; обеспечивает разделение интересов (изоляция вашего CSS и JS от вашего HTML)
  • Минусы: CSS должен быть написан заранее, поэтому содержимое :beforeили :afterне является полностью динамическим

2) Добавить новые стили непосредственно в таблицу стилей документа

Можно добавить стили непосредственно в документ таблицы стилей, в том числе использовать JavaScript :afterи :beforeстили. jQuery не предоставляет удобного ярлыка, но, к счастью, JS не так уж и сложен:

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

.addRule()и связанные .insertRule()методы довольно хорошо поддерживаются сегодня.

В качестве варианта вы также можете использовать jQuery для добавления в документ совершенно новой таблицы стилей, но необходимый код не так уж чист:

var str = "bar";
$('<style>p.special:before{content:"'+str+'"}</style>').appendTo('head');

Если мы говорим о «манипулировании» значениями, а не просто о добавлении к ним, мы также можем прочитать существующие :afterили :beforeстили, используя другой подход:

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

Мы можем заменить document.querySelector('p')на $('p')[0]при использовании jQuery, для немного более короткого кода.

  • Плюсы: любая строка может быть динамически вставлена ​​в стиль
  • Минусы: оригинальные стили не изменены, просто переопределены; повторное (ab) использование может сделать DOM произвольно большим

3) Изменить другой атрибут DOM

Вы также можете использовать attr()в своем CSS для чтения определенного атрибута DOM. ( Если браузер поддерживает :before, он также поддерживает attr(). ) Сочетая это с content:некоторыми тщательно подготовленными CSS, мы можем динамически изменять содержимое (но не другие свойства, такие как поле или цвет) :beforeи :after:

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

JS:

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

Это может быть объединено со вторым методом, если CSS не может быть подготовлен заранее:

var str = "bar";

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

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

  • Плюсы: не создает бесконечных дополнительных стилей
  • Минусы: attr в CSS можно применять только к строкам контента, а не к URL или цветам RGB
Blazemonger
источник
2
Я пытаюсь динамически установить значения глификонов (т.е. через их шестнадцатеричные значения) в :: после Пседо. content: element (например, content: "\ e043";). кажется, это не работает для меня, так что я предполагаю, что это не работает для шестнадцатеричных значений для глификонов?
user2101068
@ user2101068 Вы должны опубликовать это как новый вопрос. Мне нужно увидеть весь код, который вы используете.
Blazemonger
Blazemonger, спасибо за быстрый ответ .. к сожалению, кода довольно много, и потребовалось бы немало усилий, чтобы выхватить соответствующий код. Я уже потратил 12+ часов, пытаясь получить эту работу, и это была моя последняя попытка заставить ее работать. Мне нужно сократить свои потери. Я надеялся, что вы сможете проверить мои предположения о значениях re: hex, используя технику, описанную выше в # 3 (до фрагмента кода). Я могу вставить шестнадцатеричную строку в элемент содержимого, но он отображает текст для шестнадцатеричного значения глификона, а не фактический глификон. Впечатление не видя весь код?
user2101068
1
@ user2101068 Не используйте шестнадцатеричную строку; вместо этого скопируйте и вставьте фактический символ Unicode в атрибут HTML. jsfiddle.net/mblase75/Lcsjkc5y
Blazemonger
что касается решения 2. и 3. на самом деле вы можете предотвратить (пере) рост таблицы стилей, если вы используете: document.styleSheets [0] .insertRule (rule, index), затем, используя этот индекс, вы можете удалять правила, когда они не нужны: document. styleSheets [0] .deleteRule (index)
Пикард
158

Хотя они отображаются браузерами через CSS, как если бы они были похожи на другие настоящие элементы DOM, сами псевдоэлементы не являются частью DOM, поскольку псевдоэлементы, как следует из названия, не являются реальными элементами, и поэтому вы не можете выбирайте и манипулируйте ими напрямую с помощью jQuery (или любых других API-интерфейсов JavaScript, даже не API селекторов ). Это относится к любому псевдо-элементам, стили вы пытаетесь изменить с помощью сценария, а не только ::beforeи ::after.

Вы можете получить доступ только к стилям псевдоэлементов непосредственно во время выполнения через CSSOM (думаю window.getComputedStyle()), который не предоставляется jQuery за пределами .css(), метод, который также не поддерживает псевдоэлементы .

Вы всегда можете найти другие способы обойти это, например, например:

  • Применение стилей к псевдоэлементам одного или нескольких произвольных классов, а затем переключение между классами (см . Ответ seucolega для быстрого примера) - это идиоматический способ, поскольку он использует простые селекторы (а псевдоэлементы не являются) для различать элементы и состояния элементов по способу их использования

  • Манипулирование стилями, применяемыми к указанным псевдоэлементам, путем изменения таблицы стилей документа, что гораздо больше

BoltClock
источник
78

Вы не можете выбрать псевдоэлементы в jQuery, потому что они не являются частью DOM. Но вы можете добавить определенный класс к элементу Father и управлять его псевдоэлементами в CSS.

ПРИМЕР

В jQuery:

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

В CSS:

span.change:after { content: 'bar' }
Густаво Соуза
источник
48

Мы также можем полагаться на пользовательские свойства (или переменные CSS) , чтобы манипулировать псевдоэлементом. Мы можем прочитать в спецификации, что:

Пользовательские свойства - это обычные свойства, поэтому они могут быть объявлены для любого элемента, разрешены с помощью нормальных правил наследования и каскада , могут быть сделаны условными с помощью @media и других условных правил, могут быть использованы в атрибуте стиля HTML , могут быть прочитаны или установлены использование CSSOM и т. д.

Учитывая это, идея состоит в том, чтобы определить пользовательское свойство внутри элемента, и псевдоэлемент просто наследует его; таким образом, мы можем легко изменить его.

1) Использование встроенного стиля :

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

2) Использование CSS и классов

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

.blue {
  --color:blue;
  --content:'I am a blue element';
}
.black {
  --color:black;
}
<div class="box"></div>
<div class="box black" ></div>
<div class="box blue"></div>

3) Использование JavaScript

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

4) Использование 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>


Он также может использоваться со сложными значениями:

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

Вы можете заметить, что я рассматриваю синтаксис var(--c,value)где valueзначение по умолчанию и также называется запасным значением.

Из той же спецификации мы можем прочитать:

Значение пользовательского свойства может быть подставлено в значение другого свойства с помощью функции var (). Синтаксис var ():

var() = var( <custom-property-name> [, <declaration-value> ]? )

Первым аргументом функции является имя настраиваемого свойства, которое нужно заменить. Вторым аргументом функции, если он указан, является запасное значение, которое используется в качестве значения подстановки, когда указанное пользовательское свойство недопустимо.

И позже:

Чтобы заменить var () в значении свойства:

  1. Если пользовательское свойство, названное первым аргументом var()функции, испорчено анимацией, и var()функция используется в свойстве animation или в одном из его длинных строк, обработайте пользовательское свойство как имеющее его начальное значение для остальной части этого алгоритма.
  2. Если значение пользовательского свойства, названного первым аргументом var()функции, отличается от начального значения, замените var()функцию значением соответствующего пользовательского свойства.
  3. В противном случае, если var()функция имеет запасное значение в качестве второго аргумента, замените var()функцию запасным значением. Если var()в резерве есть какие-либо ссылки, замените их также.
  4. В противном случае свойство, содержащее var()функцию, недопустимо во время вычисления значения.

Если мы не устанавливаем пользовательское свойство ИЛИ, мы устанавливаем его initialИЛИ, оно содержит недопустимое значение, тогда будет использоваться запасное значение. Использование initialможет быть полезно в случае, если мы хотим сбросить пользовательское свойство к его значению по умолчанию.

связанные с

Как сохранить наследуемое значение в пользовательском свойстве CSS (иначе переменные CSS)?

Пользовательские свойства CSS (переменные) для блочной модели


Обратите внимание, что переменные CSS могут быть доступны не во всех браузерах, которые вы считаете актуальными (например, IE 11): https://caniuse.com/#feat=css-variables

Темани Афиф
источник
@akalata да, код требует jQuery версии 3.x .. Я добавил больше деталей и другую альтернативу с jQuery;)
Temani Afif
Как это будет работать в IE 11?
Connexo
1
@connexo как любые хорошая и современная особенность .. это не поддерживается и не будет работать caniuse.com/#feat=css-variables
Феманитяне Afif
Конечно, я знал это, и поскольку IE 11 все еще очень актуален, я пропустил эту часть информации прямо во вводной части вашего ответа.
Connexo
1
Этот ответ представляет собой подробное руководство по связыванию и модификации псевдоэлементов с помощью JavaScript с использованием переменных CSS. Большое спасибо за ваше время и за то, что поделились этой чрезвычайно ценной техникой.
LebCit
37

В соответствии с тем, что предлагает Кристиан, вы также можете сделать:

$('head').append("<style>.span::after{ content:'bar' }</style>");
Иван Чаер
источник
2
Здесь должен быть добавлен id-атрибут, чтобы элемент можно было выбрать и удалить перед добавлением нового. Если нет, может возникнуть много ненужных стилей-узлов.
KS
24

Вот способ доступа к свойствам стиля: after и: before, определенных в 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');
Nedudi
источник
11

Если вы хотите манипулировать элементами :: before или :: after sudo полностью через CSS, вы можете сделать это JS. См. ниже;

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

Обратите внимание, как <style> элемента есть идентификатор, который вы можете использовать для его удаления и добавления к нему снова, если ваш стиль изменяется динамически.

Таким образом, ваш элемент разрабатывается именно так, как вы хотите, используя CSS, с помощью JS.


источник
6

один работающий, но не очень эффективный способ - добавить правило в документ с новым содержимым и сослаться на него с помощью класса. в зависимости от того, что нужно, классу может потребоваться уникальный идентификатор для каждого значения в контенте.

$("<style type='text/css'>span.id-after:after{content:bar;}</style>").appendTo($("head"));
$('span').addClass('id-after');
Кристиан
источник
5

Вот HTML-код:

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

Вычисленный стиль на «до» был content: "VERIFY TO WATCH";

Вот мои две строки jQuery, в которых используется идея добавления дополнительного класса для конкретной ссылки на этот элемент, а затем добавления тега стиля (с тегом! Важный) для изменения CSS значения содержимого элемента sudo:

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

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

койот
источник
5

Спасибо вам всем! мне удалось сделать то, что я хотел: D http://jsfiddle.net/Tfc9j/42/ здесь посмотрите

я хотел, чтобы непрозрачность внешнего div отличалась от непрозрачности внутреннего div, и это изменилось одним щелчком мыши;) Спасибо!

   $('#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>
aimiliano
источник
Не пытайтесь append, htmlлучше
избегайте
1
Осторожно: здесь вы добавляете тег стиля к голове каждый раз, когда обрабатывается один из этих кликов. Я бы написал способ удалить старый, прежде чем добавлять новый.
pupitetris
3

Вы можете создать поддельное свойство или использовать существующее и наследовать его в таблице стилей псевдоэлемента.

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>

Кажется, это не работает для свойства "content" :(

Александр Шутау
источник
3

Это не практично, так как я не писал это для реальных целей, просто чтобы дать вам пример того, чего можно достичь.

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

в настоящее время это добавляет / или добавляет элемент Style, который содержит необходимые атрибуты, которые будут влиять на целевой элемент после псевдоэлемента.

это можно использовать как

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

а также

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

поскольку after: и before: псевдоэлементы не доступны напрямую через DOM, в настоящее время невозможно свободно редактировать Конкретные значения css.

Мой путь был просто примером, и он не подходит для практики, вы можете изменить его, попробовать некоторые свои собственные приемы и сделать его правильным для реального использования.

так что делайте свои собственные эксперименты с этим и другими!

С уважением - Адарш Хегде.

Адарш Хегде
источник
3

Я всегда добавляю свою собственную функцию утилит, которая выглядит следующим образом.

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

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

или используйте ES6

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

setPseudoElContent('.class::after', 'Hello World!');
Orlandster
источник
2

Зачем добавлять классы или атрибуты, когда вы можете просто добавить styleк заголовку

$('head').append('<style>.span:after{ content:'changed content' }</style>')
Гаурав Аггарвал
источник
2

Здесь много ответов, но ни один из них не помогает манипулировать CSS :beforeили :afterдаже не принятым.

Вот как я предлагаю это сделать. Предположим, ваш HTML похож на это:

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

И тогда вы устанавливаете его: before в CSS и проектируете его так:

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

Пожалуйста, обратите внимание, что я также установил contentатрибут в самом элементе, чтобы вы могли легко убрать его позже. Сейчас естьbutton щелчок, по которому вы хотите изменить цвет: before на зеленый и размер шрифта на 30px. Вы можете достичь этого следующим образом:

Определите CSS с вашим требуемым стилем на некотором классе .activeS :

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

Теперь вы можете изменить стиль: before, добавив класс в элемент your: before следующим образом:

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

Если вы просто хотите получить содержание :before , это можно сделать так:

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

В конечном итоге, если вы хотите динамически изменить :before содержимое с помощью jQuery, вы можете добиться этого следующим образом:

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

Нажатие на кнопку «changeBefore» выше изменится :before содержимое #somethingна «22», которое является динамическим значением.

Я надеюсь, что это помогает

ученик
источник
1

Я использовал переменные, определенные :rootвнутри, CSSчтобы изменить :after(то же самое относится и к :before) псевдоэлементу , в частности, чтобы изменить background-colorзначение для стиля, anchorопределенного .sliding-middle-out:hover:afterи contentзначение для другого anchor( #reference) в следующей демонстрации, которая генерирует случайные цвета с помощью 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("");
 }
);
Риккардо Вольпе
источник
Поддержка, за attr()исключением content, действительно скудна. Вы можете проверить caniuse.com для этого. :rootи поддержка css-переменных лучше, но все еще не так широко распространена, поскольку ее поддержка довольно нова. (также проверьте поддержку на caniuse.com)
BananaAcid
1

Я создал плагин jQuery для добавления псевдо-правил css, например, .css()для определенных элементов.

  • код плагина и тестовый пример здесь
  • Прецедент , как простой CSS изображение всплывающее окно здесь

Применение:

$('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!"'
  });
BananaAcid
источник
0

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

Вы можете использовать мой плагин для этой цели.

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>

Значения должны быть указаны, как в обычной функции jQuery.css

Кроме того, вы также можете получить значение параметра псевдоэлемента, как в обычной функции jQuery.css:

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

JS:


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

Юрий
источник
0

Кто-то еще прокомментировал добавление к элементу head с полным элементом стиля, и это неплохо, если вы делаете это только один раз, но если вам нужно сбросить его более одного раза, вы получите массу элементов стиля. Поэтому, чтобы предотвратить это, я создал пустой элемент стиля в голове с идентификатором и заменил его на innerHTML следующим образом:

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

Тогда JavaScript будет выглядеть так:

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

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

setHeight()

Теперь в моем случае мне нужно было установить высоту элемента before, основанного на высоте другого, и он будет меняться при изменении размера, поэтому с помощью этого я могу запускаться setHeight()каждый раз, когда окно изменено, и оно будет заменено <style>должным образом.

Надеюсь, это поможет тому, кто застрял, пытаясь сделать то же самое.

ZFB
источник
-1

У меня есть кое-что другое для вас, что легко и эффективно.

    <style> 
    .case-after:after { // set your properties here like eg: 
        color:#3fd309 !important; 
     } 
     .case-before:before { // set your properties here like eg: 
        color:#151715 !important; 
     }
 </style>
  // case for after
    $('#button-id').on('click', function() {
        $(".target-div").toggleClass('case-after');
    });

     // case for before
    $('#button-id').on('click', function() {
        $(".target-div").toggleClass('case-before');
    });
Coding_snakeZ
источник