Можно подумать, что на этот вопрос будет просто ответить, со всем остальным, что может сделать 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');
});
$('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