从 JavaScript 设置 CSS 伪类规则

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

因此,类似于 CSS 代码: JS 中的 a:hover { color: red }

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

125562 次浏览

不能仅对特定元素设置伪类的样式,就像不能在 inline style = “ ...”属性中设置伪类一样(因为没有选择器)。

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

#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';

较旧和较小的浏览器可能不支持这两种语法。动态样式表修改很少做,因为它很难正确完成,很少需要,而且历史上很麻烦。

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

如果您不能动态地创建样式(即从数据库或其他地方提取样式) ,那么您应该能够通过在页面主体中添加一个类来解决这个问题。

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";

一个处理跨浏览器内容的函数:

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);
}
}
};

与直接使用 Javascript 设置伪类规则不同,您可以在不同的 CSS 文件中设置不同的规则,然后使用 Javascript 关闭一个样式表并打开另一个样式表。在 分开列表(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;
}
}
}

切换样式表是实现这一点的方法。下面是一个动态构建样式表的库,这样您就可以动态地设置样式:

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

我将 小图书馆放在一起,因为我确实认为在 JS 中存在操作样式表的有效用例。理由是:

  • 设置必须计算或检索的样式——例如,从 Cookie 中设置用户的首选字体大小。
  • 设置行为(而非审美)样式,特别是对于 UI 小部件/插件开发人员。制表符,旋转木马等,往往需要一些简单的基本 CSS 功能-不应该 需求为核心功能的样式表。
  • 优于内联样式,因为 CSS 规则适用于所有当前和未来的元素,并且在 Firebug/Developer Tools 中查看时不会使 HTML 杂乱无章。

还有另一个选择。与其直接操作伪类,不如创建建模相同事物的实际类,比如“ hover”类或“已访问”类。使用通常的“样式”来设计类语法,然后您可以使用 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)"> ...

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

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

如果你使用 REACT,有一个叫 的东西,它在这里非常有用:

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

  • 如果任何一个处理程序被触发,例如通过悬停,镭会调用 setState 来更新组件上的镭特定字段 状态对象状态对象

  • 在重新渲染时,解决任何应用的交互式样式,例如: hover,通过查找元素的键或镭特定的引用 国家

这里有一个包含两个函数的解决方案: 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>

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

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

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

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

具体点就行了。然后可以动态地删除和添加样式标记。这是库和 DOM 中样式表数组的一个简单替代方案。编码愉快!

您可以考虑的一种选择是使用 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>