【问题标题】:Changing CSS pseudo-element styles via JavaScript [duplicate]通过 JavaScript 更改 CSS 伪元素样式 [重复]
【发布时间】:2011-05-27 18:13:01
【问题描述】:

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

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

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

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

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

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

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

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

【问题讨论】:

    标签: javascript css css-selectors pseudo-element selectors-api


    【解决方案1】:

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

    【讨论】:

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

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

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

    Javascript set CSS :after styles

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

    【讨论】:

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

    编辑在技术上是一种通过 JavaScript 直接更改 CSS 伪元素样式的方法,如 this answer describes,但这里提供的方法更可取。 p>

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

    CSS

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

    JavaScript

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

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

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

    【讨论】:

    • 这不是问题的答案。
    • 这甚至不相关。
    • 其实这是一个非常简单的解决方法。
    • 这根本不是一种解决方法。当您的样式可以静态定义时,这是标准操作程序。如果您在运行之前不知道样式是什么,那么这对您没有任何帮助。
    • 添加删除类名并不是直接改变元素的值。出于某种原因移动到中心点怎么样?你需要计算吗?
    【解决方案4】:

    我使用 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。非常感谢帮助:)
    【解决方案5】:

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

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

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

    【讨论】:

      【解决方案6】:

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

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

      我的问题是Retrieving or changing css rules for pseudo elements

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

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

      然后换一个:

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

      当然,您必须更改样式表和 cssRules 索引。阅读我的问题及其绘制的 cmets。

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

      【讨论】:

        【解决方案7】:

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

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

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

        更改 JavaScript 中的值:

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

        其他属性也可以这样做。

        【讨论】:

          【解决方案8】:

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

          这里有很多很好的例子: How do I load css rules dynamically in Webkit (Safari/Chrome)?

          【讨论】:

          • querySelector 不适用于 any 伪元素,因为它们是伪元素,而不是 DOM 中存在的实际元素。
          猜你喜欢
          • 2018-08-12
          • 2018-04-17
          • 2011-09-18
          • 1970-01-01
          • 2012-05-16
          • 2014-05-23
          • 2020-09-10
          相关资源
          最近更新 更多