Вибір та маніпулювання псевдоелементами CSS, такими як :: до та :: після використання jQuery


943

Чи є спосіб вибрати / маніпулювати псевдоелементами CSS, такими як ::beforeі ::after(та старою версією з однією комою), використовуючи jQuery?

Наприклад, моя таблиця стилів має таке правило:

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

Як я можу змінити "foo" на "bar" за допомогою jQuery?


4
Я зробив щось, що повинно працювати для вас: gist.github.com/yckart/5563717
yckart

1
Я ненавиджу такі коментарі щодо stackoverflow, які я збираюся написати (де коментатор запитує, чому ти не зробиш це цілком протилежним способом? ), Але: в якийсь момент слід усвідомити проблему дизайну коду та замінити цей псевдоелемент на проліт або щось таке. Я думаю, ви знаєте, на що я вказую.
zsitro

1
Прийнята відповідь відмінна. Хоча, якщо ви намагаєтеся досягти будь-якого з наступних моментів, відповідь не буде працювати: 1. Змініть стиль: до JS. 2. змінити вміст: раніше від JS Будь ласка, подивіться мою відповідь на це, якщо вона вам потрібна.
Учень


@Learner Тепер є відповідь tfor все з них: stackoverflow.com/a/49618941/8620333
теманянина Afif

Відповіді:


694

Ви також можете передати вміст псевдоелементу з атрибутом даних, а потім використовувати 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 for attr(), занадто погано, що я не зміг його використовувати з іншими властивостями, ніж content. Демо
Максим Ві.

28
Це тому, що жоден веб-переглядач ще не реалізовувався attr()поза CSS2, тоді як у CSS2 сам attr()був визначений лише для contentвластивості.
BoltClock

10
Оновлене посилання на посилання атрибутів: w3.org/TR/css3-values/#attr-notation


477

Ви можете подумати, що це відповідь на просте запитання з усім іншим, що може зробити jQuery. На жаль, проблема зводиться до технічної проблеми: css: after і: раніше правила не є частиною 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

2
Я намагаюся динамічно встановлювати значення гліфікону (тобто через їх шістнадцяткові значення) в :: після пседо. content: елемент (наприклад, content: "\ e043";). це, здається, не працює для мене, тому я припускаю, що він також не працює для шестигранних значень для гліфіконів?
user2101068

@ user2101068 Ви можете опублікувати це як нове запитання. Я б повинен побачити весь код, який ви використовуєте.
Blazemonger

Blazemonger, дякую за швидку відповідь. На жаль, код є зовсім небагато, і для того, щоб вирвати відповідний код, знадобиться зовсім небагато зусиль. Я вже витратив 12+ годин, намагаючись отримати цю роботу, і це було моїм останнім задимленим зусиллям, щоб змусити її працювати. Мені потрібно скоротити втрати. Я сподівався, що ви, можливо, зможете просто перевірити моє припущення щодо: hex значень при використанні методики, описаної у №3 вище (перед фрагментом коду). Я можу вставити шістнадцятковий рядок у елемент вмісту, але він відображає текст для шістнадцяткового значення гліфікону, а не власне гліфікону. Враження, не бачивши весь код?
user2101068

1
@ user2101068 Не використовуйте шістнадцятковий рядок; натомість скопіюйте та вставте фактичний символ Unicode в атрибут HTML. jsfiddle.net/mblase75/Lcsjkc5y
Blazemonger

що стосується рішення 2. та 3. насправді ви можете запобігти зростанню (надмірності) таблиці стилів, якщо використовуєте: document.styleSheets [0] .insertRule (правило, індекс), то за допомогою цього індексу ви можете видалити правила, коли не потрібно: документ. styleSheets [0] .deleteRule (index)
Picard

158

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

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

Ви завжди можете знайти інші шляхи навколо нього, наприклад:

  • Застосування стилів до псевдоелементів одного або декількох довільних класів, а потім перемикання між класами (див . Відповідь seucolega для швидкого прикладу) - це ідіоматичний спосіб, оскільки він використовує прості селектори (яких псевдоелементів немає) для розрізняють елементи та стани елементів, спосіб їх використання

  • Маніпулювання стилями, що застосовуються до зазначених псевдоелементів, шляхом зміни таблиці стилів документа, що набагато більше хака


78

Ви не можете вибрати псевдоелементи в jQuery, оскільки вони не є частиною DOM. Але ви можете додати певний клас до елемента елемента та керувати його псевдо елементами в 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()функція використовується у властивості анімації або в одній з її передач, розгляньте власні властивості як початкове значення для решти цього алгоритму.
  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?
коннексо

1
@connexo як будь-які хороша і сучасна особливість .. це не підтримується і не буде працювати caniuse.com/#feat=css-variables
Феманітяне Afif

Я звичайно знав, що і оскільки IE 11 все ще дуже актуальний, я пропустив цю інформацію прямо у вступній частині вашої відповіді.
Коннексо

1
Ця відповідь є поглибленим посібником щодо зв’язування та зміни псевдоелементів з JavaScript за допомогою змінних CSS. Дякую вам за ваш час та за те, що ви поділилися цим надзвичайно цінним методом.
LebCit

37

У рядку того, що пропонує Крістіан, ви також можете зробити:

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

2
Тут слід додати атрибут id, щоб елемент можна було вибрати та видалити до того, як буде доданий новий. Якщо ні, то може з'явитися багато непотрібних стилів-вузлів.
KS

24

Ось спосіб доступу: after та: до властивостей стилю, визначених у 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');

11

ЯКЩО ви хочете маніпулювати елементами :: до або :: після судо повністю через 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/ тут подивіться

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

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

Не намагайтеся append, htmlнайкраще використовувати запобігання
KingRider

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

в цей момент додається a / або додається елемент Style, який містить необхідний атрибут, який вплине на цільовий елемент після псевдоелемента.

це можна використовувати як

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

і

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

як після: і раніше: псевдоелементи не доступні безпосередньо через 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!');

2

Навіщо додавати класи чи атрибути, коли ви можете просто додати styleголову

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

2

Тут є багато відповідей, але жодна відповідь не допомагає маніпулювати 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>

Натиснувши на кнопку "змінити перед", зміна :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-pseudo, як використання .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

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

Хтось ще прокоментував додавання до елемента елемента з елементом повного стилю, і це непогано, якщо ви робите це лише один раз, але якщо вам потрібно буде скинути його ще раз, ви отримаєте тонну стильових елементів. Отже, щоб я не створив пустий елемент стилю в голові з ідентифікатором і замінив його внутрішній HTMLML таким чином:

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

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

Сподіваюся, що допоможе тому, хто застряг, намагаючись зробити те саме.


-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');
    });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.