从JavaScript设置CSS伪类规则

时间:2008-11-22 07:58:10

标签: javascript css pseudo-class

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

这是CSS代码的类比:JS中的a:hover { color: red }

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

13 个答案:

答案 0 :(得分:175)

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

您可以通过更改样式表来实现,例如添加规则:

#elid:hover { background: red; }

假设您想要影响的每个元素都有一个唯一的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';

IE当然需要自己的语法:

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

旧版和次版浏览器可能不支持这两种语法。动态样式表 - 摆弄很少,因为它很难做到正确,很少需要,而且在历史上很麻烦。

答案 1 :(得分:29)

我把small library for this放在一起,因为我认为在JS中有操作样式表的有效用例。理由是:

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

答案 2 :(得分: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);
    }
  }
};

答案 3 :(得分:6)

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

<强> CSS

.class{ /*normal css... */}
.class[special]:after{ content: 'what you want'}

<强>的javascript

  function setSpecial(id){ document.getElementById(id).setAttribute('special', '1'); }

<强> HTML

<element id='x' onclick="setSpecial(this.id)"> ...  

答案 4 :(得分:6)

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

const cssTemplateString = `.foo:[psuedoSelector]{prop: value}`;

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

const styleTag = document.createElement("style");
styleTag.innerHTML = cssTemplateString;
document.head.insertAdjacentElement('beforeend', styleTag);

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

答案 5 :(得分:5)

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

答案 6 :(得分:3)

不是直接使用javascript设置伪类规则,而是可以在不同的CSS文件中设置不同的规则,然后使用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 -->

然后使用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;
     }
   }
}

答案 7 :(得分:2)

如前所述,这不是浏览器支持的内容。

如果您没有动态提出样式(即将它们从数据库或其他东西中拉出来),您应该能够通过在页面正文中添加一个类来解决这个问题。

css看起来像是:

a:hover { background: red; }
.theme1 a:hover { background: blue; }

改变这个的javascript就像是:

// Look up some good add/remove className code if you want to do this
// This is really simplified

document.body.className += " theme1";  

答案 8 :(得分:1)

切换样式表是实现目的的方法。这是一个动态构建样式表的库,因此您可以动态设置样式:

http://www.4pmp.com/2009/11/dynamic-css-pseudo-class-styles-with-jquery/

答案 9 :(得分:0)

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

请参见下面的示例

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

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

<button onclick="changeColor('lime')">Change to lime</button>
<button onclick="changeColor('red')">Change to red</button>

答案 10 :(得分:-1)

在jquery中,您可以轻松设置悬停伪类。

$("p").hover(function(){
$(this).css("background-color", "yellow");
}, function(){
$(this).css("background-color", "pink");
});

答案 11 :(得分:-1)

如果您使用REACT,则会出现名为 radium 的内容。它在这里很有用:

  
      
  • 如果指定了交互式样式,则为道具添加处理程序,例如onMouseEnter for:hover,必要时包装现有的处理程序

  •   
  • 如果触发任何处理程序,例如通过悬停,Radium调用setState来更新组件上的Radium特定字段   州对象

  •   
  • 在重新渲染时,解析所有适用的交互式样式,例如: :悬停,通过查找元素的键或参考Radium特定的   状态
  •   

答案 12 :(得分:-1)

这是一个包含两个函数的解决方案:addCSSclass为文档添加一个新的css类,而toggleClass将其打开

该示例显示了向div添加自定义滚动条

// If newState is provided add/remove theClass accordingly, otherwise toggle theClass
function toggleClass(elem, theClass, newState) {
  var matchRegExp = new RegExp('(?:^|\\s)' + theClass + '(?!\\S)', 'g');
  var add = (arguments.length > 2 ? newState : (elem.className.match(matchRegExp) === null));

  elem.className = elem.className.replace(matchRegExp, ''); // clear all
  if (add) elem.className += ' ' + theClass;
}

function addCSSclass(rules) {
  var style = document.createElement("style");
  style.appendChild(document.createTextNode("")); // WebKit hack :(
  document.head.appendChild(style);
  var sheet = style.sheet;

  rules.forEach((rule, index) => {
    try {
      if ("insertRule" in sheet) {
        sheet.insertRule(rule.selector + "{" + rule.rule + "}", index);
      } else if ("addRule" in sheet) {
        sheet.addRule(rule.selector, rule.rule, index);
      }
    } catch (e) {
      // firefox can break here          
    }
    
  })
}

let div = document.getElementById('mydiv');
addCSSclass([{
    selector: '.narrowScrollbar::-webkit-scrollbar',
    rule: 'width: 5px'
  },
  {
    selector: '.narrowScrollbar::-webkit-scrollbar-thumb',
    rule: 'background-color:#808080;border-radius:100px'
  }
]);
toggleClass(div, 'narrowScrollbar', true);
<div id="mydiv" style="height:300px;width:300px;border:solid;overflow-y:scroll">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a eros metus. Nunc dui felis, accumsan nec aliquam quis, fringilla quis tellus. Nulla cursus mauris nibh, at faucibus justo tincidunt eget. Sed sodales eget erat consectetur consectetur. Vivamus
  a diam volutpat, ullamcorper justo eu, dignissim ante. Aenean turpis tortor, fringilla quis efficitur eleifend, iaculis id quam. Quisque non turpis in lacus finibus auctor. Morbi ullamcorper felis ut nulla venenatis fringilla. Praesent imperdiet velit
  nec sodales sodales. Etiam eget dui sollicitudin, tempus tortor non, porta nibh. Quisque eu efficitur velit. Nulla facilisi. Sed varius a erat ac volutpat. Sed accumsan maximus feugiat. Mauris id malesuada dui. Lorem ipsum dolor sit amet, consectetur
  adipiscing elit. Sed a eros metus. Nunc dui felis, accumsan nec aliquam quis, fringilla quis tellus. Nulla cursus mauris nibh, at faucibus justo tincidunt eget. Sed sodales eget erat consectetur consectetur. Vivamus a diam volutpat, ullamcorper justo
  eu, dignissim ante. Aenean turpis tortor, fringilla quis efficitur eleifend, iaculis id quam. Quisque non turpis in lacus finibus auctor. Morbi ullamcorper felis ut nulla venenatis fringilla. Praesent imperdiet velit nec sodales sodales. Etiam eget
  dui sollicitudin, tempus tortor non, porta nibh. Quisque eu efficitur velit. Nulla facilisi. Sed varius a erat ac volutpat. Sed accumsan maximus feugiat. Mauris id malesuada dui.
</div>