通过 JavaScript 更改 CSS 伪元素样式

IT技术 javascript css css-selectors pseudo-element selectors-api
2021-01-18 12:29:20

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

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

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

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

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

但是,这两个脚本都返回:

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

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

6个回答

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

节省了我的时间。谢谢。
2021-04-01 12:29:20
这真是太聪明了。优秀的解决方案。
2021-04-02 12:29:20
如果您需要针对特定​​元素,这是最佳答案。对于 IE 兼容性,包括css-vars-ponyfillcssVars({ variables: { 'scrollbar-background': '#color' } })在更新时运行
2021-04-05 12:29:20
是的,它在旧浏览器(caniuse.com/#search=css%20variables)中不起作用,但它会进入后备。
2021-04-06 12:29:20
我已经在使用 css 变量来更改滚动条的颜色,但它只是更新所有内部滚动条而不是主要滚动条(在整个页面上)。所以我通过使用 insertRule() 方法插入新的 css 规则来做到这一点。因此,当用户选择一个新主题时,它会做两件事,删除规则(如果有)并插入具有新颜色的规则。
2021-04-08 12:29:20

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

这是我发布的为伪元素添加新 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 返回新规则的索引,您可以使用它来获取对它的引用,以后可以使用它来编辑它。

content如果输入已经是字符串,我已经添加了检查甚至回退。
2021-03-23 12:29:20
这对于编写允许用户可视化对现有小部件框架(例如 jquery-ui、jquery-mobile...)的 CSS 更改的界面特别有用,这些小部件框架大量使用图标的伪元素。点赞!
2021-03-29 12:29:20
这很棒。为了之后使用规则(并删除它),我必须编辑它以实际返回 sheet.insertRule() 的结果。我还让它返回新添加的样式表,以便可以调用 .removeRule。
2021-03-31 12:29:20
我担心这个解决方案使事情过于复杂,违反了 KISS 原则和在样式表中保留样式的约定。
2021-04-08 12:29:20
正如(其他人)在您链接的帖子中指出的那样,我无法让该content物业以这种方式工作。这恰好是我需要它的全部原因,所以这很难。
2021-04-08 12:29:20

编辑:有技术上的通过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');
这不是问题的答案。
2021-03-13 12:29:20
添加删除类名不会直接改变元素的值。出于某种原因移动到中心点怎么样?你需要计算对吗?
2021-03-13 12:29:20
这甚至无关紧要。
2021-03-19 12:29:20
实际上,这是一个很好且简单的解决方法。
2021-04-05 12:29:20
这根本不是解决方法。当您的样式可以静态定义时,这是标准操作程序。如果您直到运行时才知道样式是什么,这对您无济于事。
2021-04-10 12:29:20

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

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

//JavaScript Part
document.documentElement.style.setProperty("--selection-background", "#A4CDFF");
自昨天以来,我找到的为伪元素添加样式的唯一正常答案!我正在设置 --nav-opacity-level: 0; 在 scss 中并在 js 中将其值更改为 1。单击按钮时,js 函数将值设置为 1。但是,不透明度没有像我最初设置的那样设置为 0,而是设置为 1。非常感谢帮助:)
2021-04-03 12:29:20

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

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

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