JavaScript如何通过类名来访问CSS类?

7

我需要通过名称访问CSS类,下面的代码可以工作。但是,如果我尝试使用hui["myclass"]hui[".myclass"]而不是hui[0],它会找不到。

function change_class() {
  var hui = document.styleSheets[0].rules || document.styleSheets[0].cssRules;
  hui[0].style["color"] = "#ff0000"
}
.myclass {
  color: #00aa00;
}
<div class="myclass" onclick="change_class()">Some Text</div>

编辑:我需要能够像第1行描述的那样进行访问,而不是通过页面上的单个元素进行访问,而是直接通过类名访问样式表。

所以你们都说我只能通过索引访问样式表,而不能通过类名访问吗?


我该如何通过名称进行访问? - John Smith
你不能只是使用jQuery和$('.myclass').trigger()吗? - Stan
1
不知道它的支持级别,但querySelectorAll()是一个选项。 - Whymarrh
document.getElementByClassName() 是另一种方式。 - Whymarrh
它是getElementsByClassName()。Elements是复数形式。 - Chris Sobolewski
显示剩余2条评论
6个回答

8

不,你不能通过选择器访问它们 - 它只是一个简单的列表。你首先需要为它构建一个索引:

// assuming those are the right rules (ie from the right stylesheet)
var hui = document.styleSheets[0].rules || document.styleSheets[0].cssRules;

var styleBySelector = {};
for (var i=0; i<hui.length; i++)
    styleBySelector[hui[i].selectorText] = hui[i].style;

// now access the StyleDeclaration directly:
styleBySelector[".myclass"].color = "#ff0000";

当然,这并不是一种万无一失的方法,可能会有以下情况:

  • 多个选择器,例如.myClass, .myOtherClass
  • 一个选择器的多个出现(虽然这并不重要,因为最后一个声明会覆盖之前的样式)

在盲目分配color属性之前,您应该首先检查声明是否存在。


1

是的,Bergi是正确的:
首先,您必须为样式列表构建索引。
但要注意:
如果有多个样式表,您首先必须循环遍历样式表。 因此,我想改进Bergis的解决方案:

var styleBySelector = {};
for (var j=0; j<document.styleSheets.length; j++)   {
  var styleList = document.styleSheets[j].rules || document.styleSheets[j].cssRules;
  for (var i=0; i<styleList.length; i++)
    styleBySelector[styleList[i].selectorText] = styleList[i].style;
 }

// And then invoke or set the style you wish like this:
styleBySelector[".myStyle"].color = "#ff0000";

0
document.getElementsByClassName('myclass');

将返回与之匹配的元素数组。

您还可以使用类似以下的内容:

<body>
    <div id="changethese">
        <div class="myclass" onclick="change_class()">Some Text</div>
    </div>
    <div class="myclass">div two</div>
</body>

Javascript:

var changeTheseDivs = document.getElementById('changethese');
changeTheseDivs.getElementsByClassName('myclass')

仅更改所选div中的类。

但是,此方法的支持仅适用于IE9及更高版本,因此如果可以使用JQuery,则最好使用它。

编辑:

我认为我误读了,看起来您想要更改实际的CSS规则本身,而不是更改元素上的CSS。理论上,您可以编写一个函数,以便为您查找名称相同的规则并更改其属性。我猜它应该是这样的(未经测试,应该可以工作):

function findAndChangeCSSRule(ruleName, newRule, newProperty){
    var mysheet=document.styleSheets[0];
    var myrules=mysheet.cssRules? mysheet.cssRules: mysheet.rules
    for (i=0; i<myrules.length; i++){
        if(myrules[i].selectorText.toLowerCase()==ruleName){
             targetrule=myrules[i];
             break;
        }
    }
    targetrule.style[newRule.toString()]=newProperty;
}

然后使用以下方式调用:

findAndChangeCSSRule('my_class', 'color', 'red')    

1
我不想通过任何元素进行访问。 - John Smith
我看到你说抱歉误读了,看看修改后的内容,至少可以让你开始。 - Chris Sobolewski
@JohnSmith 在这个上下文中,trough 究竟是什么意思?我猜你的意思是-through-,因为 trough 是一个食品容器,与代码无关的其他事物之一。 - Daedalus
@Daedalus 他想操作样式表,而不是内联样式。 - David Hellsing
我认为你不应该使用 toLowerCase,那可能会有很大的差别。 - Bergi
谢谢,但是其他人先回答了。 - John Smith

0

改变既定规则,这是一种方法:

// the [2] index is only because that's where JS Fiddle
// puts the user-entered CSS (from the CSS panel).
var sheets = document.styleSheets[2].rules,
    classString = 'body',
    props = ['color'], // requires a 1:1 relationship between two arrays...ugh
    to = ['#0f0'];

for (var i = 0, len = sheets.length; i < len; i++) {
    if (sheets[i].selectorText == classString) {
        for (var c = 0, leng = props.length; c < leng; c++) {
            sheets[i].style[props[c]] = to[c];
        }
    }
}​

JS Fiddle演示

还有一个略微改进的替代方案(使用对象而不是需要1:1关系的两个数组):

var sheets = document.styleSheets[2].rules,
    classString = 'body',
    propsTo = {
        'color': '#0f0'
    };

for (var i = 0, len = sheets.length; i < len; i++) {
    if (sheets[i].selectorText == classString) {
        for (var prop in propsTo) {
            if (propsTo.hasOwnProperty(prop)) {
                sheets[i].style[prop] = propsTo[prop];
            }
        }
    }
}​

JS Fiddle演示


0
要从JavaScript访问类,您只需要创建一个类列表(classist),如果它不存在的话。
document.querySelector("myDiv").classList.add("className");

这将新类添加到具有指定类名的 div 中。

否则:

document.querySelector(".className");

-1

这就是我一开始的代码,只是格式不同,现在我需要使用名称而不是 [0],请下次仔细阅读。 - John Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接