Изменение стилей псевдоэлементов CSS с помощью JavaScript

можно ли изменить стиль псевдоэлемента CSS с помощью JavaScript?

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

document.querySelector("#editor::-webkit-scrollbar-thumb:vertical").style.background = localStorage.getItem("Color");

и я также хочу иметь возможность сказать полосе прокрутки, чтобы скрыть так:

document.querySelector("#editor::-webkit-scrollbar").style.visibility = "hidden";

оба этих скрипта, однако, возвращают:

Uncaught TypeError: не удается прочитать свойство "style" null

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

6 ответов


редактировать: есть is технически способ прямого изменения стилей псевдоэлементов CSS через JavaScript, как этот ответ описывает, но метод, представленный здесь, предпочтительнее.

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

в CSS

.hidden-scrollbar::-webkit-scrollbar {
   visibility: hidden;
}

JavaScript

document.getElementById("editor").classList.add('hidden-scrollbar');

чтобы позже удалить тот же класс, вы можете использовать:

document.getElementById("editor").classList.remove('hidden-scrollbar');

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

вот ссылка на метод, который я опубликовал для добавления нового CSS для псевдо-элементов, простая версия, в которой вы устанавливаете из js

Javascript set CSS: после стилей

var addRule = (function (style) {
    var sheet = document.head.appendChild(style).sheet;
    return function (selector, css) {
        var propText = typeof css === "string" ? css : Object.keys(css).map(function (p) {
            return p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p]);
        }).join(";");
        sheet.insertRule(selector + "{" + propText + "}", sheet.cssRules.length);
    };
})(document.createElement("style"));

addRule("p:before", {
    display: "block",
    width: "100px",
    height: "100px",
    background: "red",
    "border-radius": "50%",
    content: "''"
});

sheet.insertRule возвращает индекс нового правила, которое можно использовать чтобы получить ссылку на него, которая может быть использована позже для его редактирования.


вы не можете применять стили к psuedo-элементам в JavaScript.

вы можете, однако, добавить <style> тег, чтобы глава вашего документа (или placeholding <style id='mystyles'> и изменить его содержимое), который регулирует стили. (Это будет работать лучше, чем загрузка в другую таблицу стилей, потому что embedded <style> теги имеют более высокий приоритет, чем <link>'d, убедившись, что вы не получите каскадных проблем.

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


я опубликовал вопрос, похожий на, но не полностью похожий на этот вопрос.

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

мой вопрос в извлечение или изменение правил css для псевдо-элементов

в принципе, вы можете получить стиль с помощью оператора, такого как:

document.styleSheets[0].cssRules[0].style.backgroundColor

и изменить с :

документ.стили[0].cssRules[0].стиль.backgroundColor = newColor;

вы, конечно, должны изменить таблицу стилей и индекс cssRules. Прочитайте мой вопрос и комментарии, которые он нарисовал.

Я нашел, что это работает для псевдо-элементов, а также" регулярных " элементов/стилей.


Если вам удобно с некоторой изящной деградацией в старых браузерах, вы можете использовать CSS Vars. Безусловно, самый простой из методов, которые я видел здесь и в других местах.

поэтому в вашем CSS вы можете написать:

#editor {
  --scrollbar-background: #ccc;
}

#editor::-webkit-scrollbar-thumb:vertical {
  /* Fallback */
  background-color: #ccc;
  /* Dynamic value */
  background-color: var(--scrollbar-background);
}

затем в вашем JS вы можете манипулировать этим значением в элементе # editor:

document.getElementById("#editor").style.setProperty('--scrollbar-background', localStorage.getItem("Color"));

много других примеров манипулирования CSS vars с JS здесь: https://eager.io/blog/communicating-between-javascript-and-css-with-css-variables/


похоже, querySelector не будет работать с псевдо-классами / псевдо-элементами, по крайней мере, не теми. Единственное, что я могу придумать, это динамически добавлять таблицу стилей (или изменять существующую), чтобы делать то, что вам нужно.

много хороших примеров здесь: как динамически загружать правила css в Webkit (Safari/Chrome)?