87

是否可以通过 JavaScript 更改 CSS 伪元素样式?

例如,我想像这样动态设置滚动条的颜色:

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

而且我还希望能够告诉滚动条像这样隐藏:

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

然而,这两个脚本都返回:

未捕获的类型错误:无法读取 null 的属性“样式”

还有其他方法可以解决这个问题吗?
跨浏览器的互操作性并不重要,我只需要它在 webkit 浏览器中工作即可。

4

8 回答 8

51

如果您对旧浏览器中的一些优雅降级感到满意,您可以使用 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"));

此处有许多其他使用 JS 操作 CSS 变量的示例:https ://eager.io/blog/communicating-between-javascript-and-css-with-css-variables/

于 2018-04-18T20:29:53.157 回答
30

要编辑您没有直接引用的现有样式表,需要迭代页面上的所有样式表,然后迭代每个样式表中的所有规则,然后再匹配选择器的字符串。

这是我发布的为伪元素添加新 CSS 的方法的参考,这是您从 js 设置的简单版本

Javascript 设置 CSS :after 样式

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返回新规则的索引,您可以使用它来获取对它的引用,以后可以使用它来编辑它。

于 2011-11-08T13:55:38.437 回答
26

编辑:技术上有一种通过 JavaScript 直接更改 CSS 伪元素样式的方法,正如这个答案所描述的那样,但这里提供的方法更可取。

在 JavaScript 中最接近更改伪元素样式的方法是添加和删除类,然后将伪元素与这些类一起使用。隐藏滚动条的示例:

CSS

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

JavaScript

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

要稍后删除同一类,您可以使用:

document.getElementById("editor").classList.remove('hidden-scrollbar');
于 2012-08-31T00:47:00.633 回答
16

我通过使用 CSS 自定义属性执行以下操作更改了 ::selection 伪元素的背景:

/*CSS Part*/
:root {
    --selection-background: #000000;
}
#editor::selection {
    background: var(--selection-background);
}

//JavaScript Part
document.documentElement.style.setProperty("--selection-background", "#A4CDFF");
于 2020-02-05T22:12:56.010 回答
7

您不能将样式应用于 JavaScript 中的伪元素。

但是,您可以将<style>标签附加到文档的头部(或使用占位符<style id='mystyles'>并更改其内容),从而调整样式。(这比在另一个样式表中加载更好,因为嵌入<style>标签的优先级高于<link>'d ,确保您不会遇到级联问题。

或者,您可以使用不同的类名,并在原始样式表中使用不同的伪元素样式定义它们。

于 2011-11-08T05:44:48.747 回答
4

我发布了一个类似于但不完全喜欢这个问题的问题。

我找到了一种检索和更改伪元素样式的方法,并询问了人们对该方法的看法。

我的问题是在检索或更改伪元素的 CSS 规则

基本上,您可以通过以下语句获得样式:

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

并更改一个:

document.styleSheets[0].cssRules[0].style.backgroundColor = newColor;

当然,您必须更改样式表和 cssRules 索引。阅读我的问题和它得出的评论。

我发现这适用于伪元素以及“常规”元素/样式。

于 2015-10-07T23:57:57.067 回答
2

一个老问题,但我在尝试动态更改元素:before选择器内容的颜色时遇到了这个问题。

我能想到的最简单的解决方案是使用 CSS 变量,这个解决方案在提出问题时不适用:

"#editor::-webkit-scrollbar-thumb:vertical {
    background: --editorScrollbarClr
}

更改 JavaScript 中的值:

document.body.style.setProperty(
    '--editorScrollbarClr', 
     localStorage.getItem("Color")
);

其他属性也可以这样做。

于 2019-07-21T13:38:26.790 回答
0

看起来 querySelector 不适用于伪类/伪元素,至少不是那些。我唯一能想到的就是动态添加样式表(或更改现有的样式表)来满足您的需要。

这里有很多很好的例子: 如何在 Webkit (Safari/Chrome) 中动态加载 css 规则?

于 2010-12-19T04:07:34.883 回答