使用getElementsByClassName更改多个类?

时间:2013-11-11 14:39:01

标签: javascript

我一直试图找到我认为应该是一个简单修复的答案,但我必须查看一些事情。我是Javascript的新手,对jQuery不太满意。此外,我想在javascript中完全这样做,因为这是我第一次尝试它。我有一个使用复选框的项目,我有一些帮助到达我的位置,但我正在尝试使用document.getElementsByClassName导致样式更改为多个类。

我已使用.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;}
}}

**现在我需要弄清楚如何使用由2个选项共享但不互相干扰的复选框。例如;

“单一图形使用”复选框仅适用于贝尼尼,但复选框“银色完成”适用于贝尼尼和毕加索。如果选中“单个图形使用”,如何使其仍然启用,但如果选中“Clip-in Top Rail”,则如何启用?

如果需要,这里有一些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>

感谢您提供的任何帮助。

我已经更新了代码,这里是我所拥有的链接。我接近拥有我需要的东西(非常感谢每个人)我现在唯一想不到的是;

复选框'Tape-in​​ Bottom Rail'需要显示适用于'bernini和picasso'类的所有复选框。现在,如果您单击该复选框,它可以工作。但是,如果您还选择仅适用于'bernini'或'picasso'的复选框,然后取消选中它,则选项变为可用,但不应该。有人建议如何减轻这种情况吗?

http://jsfiddle.net/g_borg/48uhn/1/

6 个答案:

答案 0 :(得分:5)

而不是document.getElementsByClassName使用document.querySelectorAll并传入CSS 选择器(而不仅仅是类名):

var berninis = document.querySelectorAll('.picasso, .matisse');
for(var i = 0; i < berninis.length; i++) {
  berninis[i].style.color="#d1d1d1";
}

答案 1 :(得分:2)

为了清除更多的混淆,可以getElementsByClassName中有多个类名,但它会选择所有列出的类的元素。< / p>

换句话说,

document.getElementsByClassName('picasso matisse')

将选择此

<span class="picasso matisse"></span>

但不是这些

<span class="picasso"></span>
<span class="matisse"></span>

答案 2 :(得分:0)

getElementsByClassName()一次只能在一个类上运行。

你可以改变你的功能,看起来像这样:

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

我所做的是创建了一个你想要经历的类数组,使用你想要使用的两个类来启动数组,然后我们简单地遍历数组。

我建议你试试jQuery。它易于使用,这种东西正是它的意思。使用普通的vanilla JS来处理DOM有时会很麻烦。

答案 3 :(得分:0)

您必须复制粘贴“document.getElementById(”att_XYZ“)。disabled = true;”十几次表明你采取了错误的做法。这是因为如果你想在你的HTML中添加另一个复选框,你也需要变换你的Javascript代码,这是非常不愉快的,因为它会导致错误。

我不是手工命名每一个元素,而是用单个类名对需要同时控制的元素进行分组。例如:

<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 />

然后,在您的代码中,您可以编写

var allCheckboxesFromGroupA = $('input.groupA');
foreach(allCheckboxesFromGroupA as item) {
   item.disabled = true;
}

编辑:如果您不想使用jQuery,该方法仍然适用:

var allCheckboxesFromGroupA = document.getElementsByClassName('groupA');
foreach(allCheckboxesFromGroupA as item) {
   item.disabled = true;
}

答案 4 :(得分:0)

你可以分两步完成。首先使用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

答案 5 :(得分:0)

我强烈建议改变你的做法,可能会改为:

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

JS Fiddle demo

在最新的浏览器中,上述内容可以大大缩短为:

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

JS Fiddle demo