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

827

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

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

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

Как я могу изменить "foo" на "bar" с помощью jQuery?

  • 1
    Похожие страницы : stackoverflow.com/questions/3743513/…
  • 4
    Я сделал то, что должно работать для вас: gist.github.com/yckart/5563717
Показать ещё 3 комментария
Теги:
pseudo-element
jquery-selectors

22 ответа

637
Лучший ответ

Вы также можете передать содержимое псевдоэлементу атрибуту данных, а затем использовать 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 ? Я удивлен, что никогда не слышал об этом ...
  • 5
    Здесь: w3.org/TR/css3-values/#attribute
Показать ещё 11 комментариев
433

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

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


Я начну с того, что считается "лучшим":

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

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

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

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

$('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>
  • Плюсы: Легко реализовать с помощью 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+'";');

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() и соответствующие методы .insertRule() довольно хорошо поддерживаются сегодня.

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

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>

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

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>

Мы можем заменить 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');
});

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

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

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>
  • Плюсы: Не создает бесконечные дополнительные стили
  • Минусы: attr в CSS могут применяться только к строкам контента, а не к URL-адресам или цветам RGB
  • 2
    Я пытаюсь динамически установить значения глифов (то есть, через их шестнадцатеричные значения) в :: после Пседо. content: element (например, content: "\ e043";). кажется, это не работает для меня, так что я предполагаю, что это не работает для шестнадцатеричных значений для глификонов?
  • 0
    @ user2101068 Вы должны опубликовать это как новый вопрос. Мне нужно увидеть весь код, который вы используете.
Показать ещё 3 комментария
159

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

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

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

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

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

72

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

ПРИМЕР

В jQuery:

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

В CSS:

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

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

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

Вот способ доступа: свойства after и: before style, определенные в 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');
  • 3
    Невозможно сделать setProperty ? я стараюсь не работать
19

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

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

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

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

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

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

.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) Использование 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) Использование 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>
  • 1
    Отличное решение, спасибо! Я застрял с версией заказа jQuery (так что это не работало), но переключение на простой JS работает как чудо.
  • 0
    @akalata да, код требует jQuery версии 3.x .. Я добавил больше деталей и другую альтернативу с jQuery;)
Показать ещё 5 комментариев
11

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

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

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

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

  • 1
    это очень круто по другой причине: если вы создаете плагин jquery и не хотите требовать включения таблицы стилей, но должны заранее определить определенные стили, это отличный способ сделать это!
11

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

Ответ должен быть "Да" и "Нет". Вы не можете выбрать элемент с помощью псевдоселектора, но вы можете добавить новое правило в таблицу стилей с помощью javascript.

Я сделал что-то, что должно сработать для вас:

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/

5

Вот HTML:

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

Вычисленный стиль в 'before' был content: "VERIFY TO WATCH";

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

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

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

4

Спасибо всем! мне удалось сделать то, что я хотел: 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>
  • 0
    Не пытайтесь append , используйте html лучше всего предотвратить
  • 0
    +1. Это именно то, что я искал, чтобы изменить непрозрачность div. Другие ответы очень подробны, но все они сосредоточены на добавлении стилей, а не на изменении существующих. Спасибо!
Показать ещё 1 комментарий
4

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

$("<style type='text/css'>span.id-after:after{content:bar;}</style>").appendTo($("head"));
$('span').addClass('id-after');
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, который содержит ваш необходимый атрибут, который будет влиять на целевой элемент после элемента Pseudo.

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

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

и

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

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

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

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

привет - Адарш Хедде.

2

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

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

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

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

1

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

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!');
1

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

Вот как я предлагаю это сделать. Предположим, что ваш HTML выглядит следующим образом:

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

И затем вы устанавливаете его: раньше в CSS и проектируете его так:

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

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

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

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

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

<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", что является динамическим значением.

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

0

Я создал плагин 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!"'
  });

0

Я использовал переменные, определенные в :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("");
 }
);
  • 0
    Поддержка attr() за исключением content , действительно недостаточна. Вы можете проверить caniuse.com для этого. Поддержка :root и css-переменных лучше, но все еще не так широко распространена, поскольку поддержка для нее довольно нова. (также проверьте поддержку на caniuse.com)
0

Кто-то еще прокомментировал добавление элемента head с полным элементом стиля, и это неплохо, если вы делаете это только один раз, но если вам нужно reset, это не один раз, вы получите тонну стиль элементов. Поэтому, чтобы я не создал пустой элемент стиля в голове с идентификатором и заменил его 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> правильно.

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

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:

(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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню