从JavaScript设置CSS伪类规则

use*_*882 119 javascript css pseudo-class css-in-js

我正在寻找一种方法来改变JavaScript类的伪类选择器(例如:link,:hover等)的CSS规则.

所以CSS代码的类比:a:hover { color: red }在JS中.

我无法在其他任何地方找到答案; 如果有人知道这是浏览器不支持的东西,那么这也是一个有用的结果.

bob*_*nce 184

您不能单独为特定元素设置伪类,就像在内联样式="..."属性中没有伪类一样(因为没有选择器).

您可以通过更改样式表来完成此操作,例如通过添加规则:

#elid:hover { background: red; }
Run Code Online (Sandbox Code Playgroud)

假设您想要影响的每个元素都有一个唯一的ID,以允许它被选中.

理论上,您需要的文档是http://www.w3.org/TR/DOM-Level-2-Style/Overview.html,这意味着您可以使用以下语法(给定预先存在的嵌入或链接样式表):

document.styleSheets[0].insertRule('#elid:hover { background-color: red; }', 0);
document.styleSheets[0].cssRules[0].style.backgroundColor= 'red';
Run Code Online (Sandbox Code Playgroud)

IE当然需要自己的语法:

document.styleSheets[0].addRule('#elid:hover', 'background-color: red', 0);
document.styleSheets[0].rules[0].style.backgroundColor= 'red';
Run Code Online (Sandbox Code Playgroud)

较旧和次要的浏览器可能不支持任何一种语法.动态样式表 - 摆弄很少进行,因为它很难让你做对,很少需要,而且在历史上很麻烦.

  • 为什么不选择这个作为答案呢? (31认同)
  • Firefox:"错误:操作不安全." (2认同)
  • 不推荐操作样式表以仅将样式应用于特定元素,因为它会导致浏览器在每次更改样式表时重排整个文档.http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/ (2认同)

Dav*_*ang 29

为此,我将一个小型库汇集在一起,因为我认为在JS中有一些有效的用例来操作样式表.原因是:

  • 设置必须计算或检索的样式 - 例如,从cookie设置用户的首选字体大小.
  • 设置行为(非美学)风格,尤其是UI小部件/插件开发人员.标签,旋转木马等通常只需要一些基本的CSS来运行 - 不应该要求核心功能的样式表.
  • 优于内联样式,因为CSS规则适用于所有当前和未来的元素,并且在Firebug/Developer Tools中查看时不会混乱HTML.

  • 看起来真的很好 (3认同)

小智 16

一个处理跨浏览器的功能:

addCssRule = function(/* string */ selector, /* string */ rule) {
  if (document.styleSheets) {
    if (!document.styleSheets.length) {
      var head = document.getElementsByTagName('head')[0];
      head.appendChild(bc.createEl('style'));
    }

    var i = document.styleSheets.length-1;
    var ss = document.styleSheets[i];

    var l=0;
    if (ss.cssRules) {
      l = ss.cssRules.length;
    } else if (ss.rules) {
      // IE
      l = ss.rules.length;
    }

    if (ss.insertRule) {
      ss.insertRule(selector + ' {' + rule + '}', l);
    } else if (ss.addRule) {
      // IE
      ss.addRule(selector, rule, l);
    }
  }
};
Run Code Online (Sandbox Code Playgroud)


Nic*_*ons 7

您可以考虑的一种选择是使用 CSS 变量。这个想法是将要更改的属性设置为 CSS 变量。然后,在 JS 中更改该变量的值。

请参阅下面的示例

function changeColor(newColor) {
  document.documentElement.style.setProperty("--anchor-hover-color", newColor);
  // ^^^^^^^^^^^-- select the root 
}
Run Code Online (Sandbox Code Playgroud)
:root {
  --anchor-hover-color: red;
}

a:hover { 
  color: var(--anchor-hover-color); 
}
Run Code Online (Sandbox Code Playgroud)
<a href="#">Hover over me</a>

<button onclick="changeColor('lime')">Change to lime</button>
<button onclick="changeColor('red')">Change to red</button>
Run Code Online (Sandbox Code Playgroud)


Ser*_*reu 6

我的诀窍是使用属性选择器.通过javascript更容易设置属性.

CSS

.class{ /*normal css... */}
.class[special]:after{ content: 'what you want'}
Run Code Online (Sandbox Code Playgroud)

JavaScript的

  function setSpecial(id){ document.getElementById(id).setAttribute('special', '1'); }
Run Code Online (Sandbox Code Playgroud)

HTML

<element id='x' onclick="setSpecial(this.id)"> ...  
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案使用jQuery - 引入jQuery大小的依赖关系这个简单的东西,当提问者要求纯Javascript时,这很糟糕. (4认同)

小智 6

只需将css放在模板字符串中即可.

const cssTemplateString = `.foo:[psuedoSelector]{prop: value}`;
Run Code Online (Sandbox Code Playgroud)

然后创建一个样式元素并将该字符串放在样式标记中并将其附加到文档.

const styleTag = document.createElement("style");
styleTag.innerHTML = cssTemplateString;
document.head.insertAdjacentElement('beforeend', styleTag);
Run Code Online (Sandbox Code Playgroud)

特殊性将照顾其余部分.然后,您可以动态删除和添加样式标记.这是库的简单替代方法,并且在DOM中使用样式表数组.快乐的编码!


TRi*_*RiG 5

您可以在不同的 CSS 文件中设置不同的规则,然后使用 Javascript 关闭一个样式表并打开另一个样式表,而不是直接使用 javascript 设置伪类规则。A List Apart中描述了一种方法(更多详细信息参见 qv.)。

将 CSS 文件设置为,

<link rel="stylesheet" href="always_on.css">
<link rel="stylesheet" title="usual" href="preferred.css"> <!-- on by default -->
<link rel="alternate stylesheet" title="strange" href="alternate.css"> <!-- off by default -->
Run Code Online (Sandbox Code Playgroud)

然后使用 javascript 在它们之间切换:

function setActiveStyleSheet(title) {
   var i, a, main;
   for(i=0; (a = document.getElementsByTagName("link")<i>); i++) {
     if(a.getAttribute("rel").indexOf("style") != -1
        && a.getAttribute("title")) {
       a.disabled = true;
       if(a.getAttribute("title") == title) a.disabled = false;
     }
   }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

还有另一种选择.不是直接操作伪类,而是创建模拟相同事物的真实类,如"悬停"类或"访问过的"类.使用通常的"."来设置类的样式.语法,然后您可以使用JavaScript在相应的事件触发时添加或删除元素中的类.

  • 这不适用于 :before 和 :after 伪类。 (2认同)
  • @jbyrd, `:before` 和 `:after` 是伪元素,而不是类。 (2认同)