Есть ли способ выбрать / манипулировать псевдоэлементами CSS, такими как ::before
а также ::after
(и старая версия с одной точкой с запятой), используя jQuery?
Например, моя таблица стилей имеет следующее правило:
.span::after{ content:'foo' }
Как я могу изменить ‘foo’ на ‘bar’, используя jQuery?
Вы также можете передать содержимое в псевдоэлемент с атрибутом данных, а затем использовать 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';
}
Вы могли бы подумать, что это будет простой вопрос, со всем остальным, что может сделать jQuery. К сожалению, проблема сводится к технической проблеме: css: after и: before правила не являются частью DOM, и, следовательно, не может быть изменено с использованием методов DOM jQuery.
Там являются способы манипулирования этими элементами с помощью обходных путей JavaScript и / или CSS; какой из них вы используете, зависит от ваших конкретных требований.
Я собираюсь начать с того, что широко считается «лучшим» подходом:
При таком подходе вы уже создали класс в своем 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>
:before
или же :after
не полностью динамическийМожно использовать 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, для немного более короткого кода.
Вы также можете использование 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Хотя они отображаются браузерами через CSS, как если бы они были похожи на другие настоящие элементы DOM, сами псевдоэлементы не являются частью DOM, потому что псевдоэлементы, как следует из названия, не являются реальными элементами, и поэтому вы не можете выберите и манипулируйте ими напрямую с помощью jQuery (или любой JavaScript API в этом отношении, даже не API селекторов). Это относится ко всем псевдоэлементам, стили которых вы пытаетесь изменить с помощью скрипта, а не только к ::before
а также ::after
,
Вы можете получить доступ только к стилям псевдоэлементов непосредственно во время выполнения через CSSOM (подумайте window.getComputedStyle()
), который не доступен через jQuery .css()
, метод, который также не поддерживает псевдоэлементы.
Вы всегда можете найти другие способы обойти это, хотя, например:
Применение стилей к псевдоэлементам одного или нескольких произвольных классов, а затем переключение между классами (см. ответ seucolega для быстрого примера) — это идиоматический способ, поскольку он использует простые селекторы (которые не являются псевдоэлементами), чтобы различать элементы и состояния элементов, так, как они предназначены для использования
Манипулирование стилями, применяемыми к указанным псевдоэлементам, путем изменения таблицы стилей документа, что гораздо больше
Вы не можете выбрать псевдоэлементы в jQuery, потому что они не являются частью DOM.
Но вы можете добавить определенный класс к элементу Father и управлять его псевдоэлементами в CSS.
В jQuery:
<script type="text/javascript">
$('span').addClass('change');
</script>
В CSS:
span.change:after { content: 'bar' }
В соответствии с тем, что предлагает Кристиан, вы также можете сделать:
$('head').append("<style>.span::after{ content:'bar' }</style>");
Вот способ доступа к свойствам стиля: 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');
Мы также можем положиться на Пользовательские свойства 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>
Если вы хотите манипулировать элементами :: before или :: after sudo полностью через CSS, вы можете сделать это с помощью JS. Увидеть ниже;
jQuery('head').append('<style id="mystyle" type="text/css"> /* your styles here */ </style>');
Обратите внимание, как <style>
Элемент имеет идентификатор, который вы можете использовать для его удаления и добавления к нему снова, если ваш стиль изменяется динамически.
Таким образом, ваш элемент разрабатывается именно так, как вы хотите, используя CSS, с помощью JS.