javascript 使用 getElementsByClassName 更改多个类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19908959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Change multiple classes with getElementsByClassName?
提问by g_borg
I've been trying to find the answer to what I think should be an easy fix but I must be looking over something. I'm very new to Javascript and not comfortable with jQuery. Also I am wanting to do this entirely in javascript as this is my 1st real attempt with it. I have a project that uses check boxes and I've had some help getting to where I am but I'm trying to use document.getElementsByClassName to cause a style change to multiple classes.
我一直试图找到我认为应该很容易解决的问题的答案,但我必须在寻找一些东西。我对 Javascript 很陌生,对 jQuery 不满意。此外,我想完全在 javascript 中执行此操作,因为这是我第一次真正尝试使用它。我有一个使用复选框的项目,我得到了一些帮助,但我正在尝试使用 document.getElementsByClassName 来更改多个类的样式。
I've updated my script to the following, using the .querySelectorAll option. I've also added an else to remove the grey text color and enable the check boxes.
我已使用 .querySelectorAll 选项将我的脚本更新为以下内容。我还添加了一个 else 来删除灰色文本颜色并启用复选框。
function bannerBernini() {
if (document.checkForm1.att_2.checked || document.checkForm1.att_5.checked || document.checkForm1.att_6.checked || document.checkForm2.att_9.checked || document.checkForm2.att_15.checked || document.checkForm3.att_23.checked)
{
var berninis = document.querySelectorAll('.picasso, .matisse');
for(var i = 0; i < berninis.length; i++) {
berninis[i].style.color="#d1d1d1";}
var not_bernini = document.querySelectorAll('#att_3, #att_10, #att_11, #att_13, #att_14, #att_16, #att_17, #att_18, #att_19, #att_20, #att_21, #att_22, #att_24');
for (var j = 0; j < not_bernini.length; j++){
not_bernini[j].disabled=true;}
}
else
{
var berninis = document.querySelectorAll('.picasso, .matisse');
for(var i = 0; i < berninis.length; i++) {
berninis[i].style.color="";}
var not_bernini = document.querySelectorAll('#att_3, #att_10, #att_11, #att_13, #att_14, #att_16, #att_17, #att_18, #att_19, #att_20, #att_21, #att_22, #att_24');
for (var j = 0; j < not_bernini.length; j++){
not_bernini[j].disabled=false;}
}}
**Now I need to figure out how to have check boxes that are shared by 2 of options but not interfere with each other. For instance;
**现在我需要弄清楚如何让两个选项共享但不相互干扰的复选框。例如;
The checkbox 'Single graphic use' only applies to Bernini but the check box 'Silver Finish' applies to both Bernini and Picasso. How do I make that one still enabled when 'Single graphic use' is checked, but not enabled if 'Clip-in Top Rail' is checked?
复选框“单一图形使用”仅适用于贝尼尼,但复选框“银色饰面”适用于贝尼尼和毕加索。如何在选中“单一图形使用”时仍然启用该功能,但如果选中“夹入式顶部导轨”则不启用?
Here is some of the html if needed
如果需要,这里是一些 html
<div id="column1" style="width:250px; padding:5px 10px 5px 10px; float:left">
<form name="checkForm1" id="checkForm1">
<span class="all"><input type="checkbox" id="att_1" name="att_1" class="all" onChange="">Single-sided</span><br />
<span class="bernini"><input type="checkbox" id="att_2" name="att_2" onChange="bannerBernini();">Visible Banner: 33.5" x 36"-78.7"</span><br />
<span class="picasso"><input type="checkbox" id="att_3" name="att_3" onChange="">Medium Duty Spring System</span><br />
<span class="matisse"><input type="checkbox" id="att_4" name="att_4" onChange="">Clip-in Top Rail</span><br />
<span class="bernini"><input type="checkbox" id="att_5" name="att_5" onChange="bannerBernini();">Adjustable Twist Locking Pole</span><br />
<span class="bernini"><input type="checkbox" id="att_6" name="att_6" onChange="bannerBernini();">Single graphic use</span><br />
<span class="all"><input type="checkbox" id="att_7" name="att_7" onChange="">Carrying case included</span><br />
<span class="all"><input type="checkbox" id="att_8" name="att_8" onChange="">Silver finish</span><br />
</form>
Thanks for any assistance you can supply.
感谢您提供的任何帮助。
I've updated code and here is a link to what I have. I'm close to having what I need (MANY THANKS TO EVERYONE) The only thing I can't figure out now is;
我已经更新了代码,这里是我所拥有的链接。我即将拥有我需要的东西(非常感谢所有人)我现在唯一想不通的是;
The check box 'Tape-in Bottom Rail' needs to display all the check boxes that apply to the 'bernini and picasso' classes. Right now if you click that check box it works. BUT if you also choose a check box that ONLY applies to 'bernini' OR 'picasso' then uncheck it, options become available that shouldn't. Anyone have a suggestion on how to alleviate that?
“Tape-in Bottom Rail”复选框需要显示适用于“bernini 和 picasso”类的所有复选框。现在,如果您单击该复选框,它将起作用。但是,如果您还选择了一个仅适用于“bernini”或“picasso”的复选框,然后取消选中它,则不应该使用的选项将可用。有人对如何缓解这种情况有任何建议吗?
回答by rgthree
Instead of document.getElementsByClassName
use document.querySelectorAll
and pass in the CSS selector(not just the classnames):
而不是document.getElementsByClassName
使用document.querySelectorAll
和传递 CSS选择器(不仅仅是类名):
var berninis = document.querySelectorAll('.picasso, .matisse');
for(var i = 0; i < berninis.length; i++) {
berninis[i].style.color="#d1d1d1";
}
回答by Alex Wittig
To maybe clear up a little more confusion, you canhave multiple class names in getElementsByClassName
, but it will select elements having alllisted classes.
为了消除更多的困惑,您可以在 中有多个类名getElementsByClassName
,但它会选择具有所有列出类的元素。
In other words,
换句话说,
document.getElementsByClassName('picasso matisse')
will select this
会选择这个
<span class="picasso matisse"></span>
but not these
但不是这些
<span class="picasso"></span>
<span class="matisse"></span>
回答by HaukurHaf
getElementsByClassName() only works on one class at a time.
getElementsByClassName() 一次只能作用于一个类。
You could change your function so it looks something like this:
您可以更改您的功能,使其看起来像这样:
function bannerBernini()
{
if (document.checkForm1.att_2.checked || document.checkForm1.att_5.checked || document.checkForm1.att_6.checked || document.checkForm2.att_9.checked || document.checkForm2.att_15.checked || document.checkForm3.att_23.checked)
{
var classes = ['picasso','matisse']
for (var j = 0; j < classes.length; j++)
{
var berninis = document.getElementsByClassName(classes[j]);
for(var i = 0; i < berninis.length; i++) {
berninis[i].style.color="#d1d1d1";}
{
document.getElementById("Picasso").style.display="none";
document.getElementById("Matisse").style.display="none";
document.getElementById("att_3").disabled=true;
document.getElementById("att_10").disabled=true;
document.getElementById("att_11").disabled=true;
document.getElementById("att_13").disabled=true;
document.getElementById("att_14").disabled=true;
document.getElementById("att_16").disabled=true;
document.getElementById("att_17").disabled=true;
document.getElementById("att_18").disabled=true;
document.getElementById("att_19").disabled=true;
document.getElementById("att_20").disabled=true;
document.getElementById("att_21").disabled=true;
document.getElementById("att_22").disabled=true;
document.getElementById("att_24").disabled=true;
}
}}}
What I did is that I created an array of classes you want to go through, initilized the array with the two classes you want to use and then we simply iterate through the array.
我所做的是我创建了一个你想要遍历的类数组,用你想要使用的两个类初始化数组,然后我们简单地遍历数组。
I'd recommend you try jQuery. It's easy to use and this kind of stuff is exactly what it was meant for. Using plain vanilla JS to work with the DOM is sometimes a hassle.
我建议你尝试 jQuery。它很容易使用,这种东西正是它的用途。使用普通的 JS 来处理 DOM 有时会很麻烦。
回答by Alex Weinstein
The fact that you have to copy-paste "document.getElementById("att_XYZ").disabled=true;" a dozen times is a sign that you have the wrong approach. This is because if you wanted to add another checkbox to your HTML, you would need to morph your Javascript code as well, which is very unpleasant as it causes bugs.
您必须复制粘贴“document.getElementById("att_XYZ").disabled=true;” 十几次表明你的方法是错误的。这是因为如果您想在 HTML 中添加另一个复选框,您还需要修改您的 Javascript 代码,这非常令人不快,因为它会导致错误。
Instead of naming every single element by hand, what I would do is group the elements that need to be controlled at the same time with a single class name. For example:
我不会手动命名每个元素,而是将需要同时控制的元素用一个类名分组。例如:
<span class="bernini"><input class="groupA" type="checkbox" id="att_2" name="att_2" onChange="bannerBernini();">Visible Banner: 33.5" x 36"-78.7"</span><br />
<span class="picasso"><input class="groupA" type="checkbox" id="att_3" name="att_3" onChange="">Medium Duty Spring System</span><br />
Then, in your code, you could write
然后,在您的代码中,您可以编写
var allCheckboxesFromGroupA = $('input.groupA');
foreach(allCheckboxesFromGroupA as item) {
item.disabled = true;
}
EDIT: if you don't want to use jQuery, the approach still applies:
编辑:如果您不想使用 jQuery,该方法仍然适用:
var allCheckboxesFromGroupA = document.getElementsByClassName('groupA');
foreach(allCheckboxesFromGroupA as item) {
item.disabled = true;
}
回答by Maarten Janssen
You could do it in two steps. First get the elements with the picasso class and then add the lements with the matisse class to the array:
你可以分两步完成。首先获取带有 picasso 类的元素,然后将带有 matisse 类的元素添加到数组中:
var berninis = document.getElementsByClassName('picasso');
berninis.concat (document.getElementsByClassName('matisse'));
for(var i = 0; i < berninis.length; i++) { // Rest of your code here
回答by David says reinstate Monica
I'd strongly suggest changing your approach, possibly to the following:
我强烈建议改变你的方法,可能是以下几点:
function bannerBernini (e){ // e is the 'change' event, passed automagically to the function.
var _self = this, // the form itself
changed = e.target, // the changed element
spans = _self.getElementsByTagName('span'),
spanClass = e.target.parentNode.tagName.toLowerCase() == 'span' ? e.target.parentNode.className : false,
children; // a stored variable for later
// if the span has a className:
if (spanClass) {
// iterate over all the spans in the form:
for (var i = 0, len = spans.length; i < len; i++){
// if the class of the parent span is *not* in the span we're iterating over:
if (spans[i].className.indexOf(spanClass) == -1){
// store the childNodes of the current span in the previously-declared variable:
children = spans[i].childNodes;
// iterate over those childNodes:
for (var c = 0, cL = children.length; c < cL; c++){
// if the childnode is an element (nodeType === 1), and is of type == 'checkbox':
if (children[c].nodeType === 1 && children[c].type == 'checkbox') {
// set the current checkbox/childNode's disabled attribute to true, or false (the checked-state of the changed element):
children[c].disabled = changed.checked;
}
}
}
}
}
}
// the form we want to act upon:
var form = document.getElementById('checkForm1');
// adding an event-listener and binding an event-handler (for that event):
form.addEventListener('change', bannerBernini);
In up-to-date browsers, though, the above can be shortened considerably to:
但是,在最新的浏览器中,上述内容可以大大缩短为:
function bannerBernini(e) { // again the event ('e') passed automagically
// the className of the parent span element to the changed element:
var filterClass = e.target.parentNode.className;
// if we have a filterClass:
if (filterClass) {
/* we're using array.prototype.forEach to iterate over the collection
returned by "document.querySelectorAll('span')", the 'a' represents
the array element we're iterating over currently: */
[].forEach.call(document.querySelectorAll('span'), function(a){
/* setting the disabled property of the (first/only) input of
type="checkbox" to:
false, if the filterClass is 'all',
or the classList of 'a' contains the filterClass *and*
the changed-element is now checked. */
a.querySelector('input[type="checkbox"]').disabled = !(filterClass === 'all' || a.classList.contains(filterClass)) && e.target.checked;
});
}
}
var form = document.getElementById('checkForm1');
form.addEventListener('change', bannerBernini);