Вы могли бы подумать, что это будет простой вопрос, со всем остальным, что может сделать 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