Javascript为多个元素设置CSS类(一个元素集,其余元素未设置)

时间:2019-06-25 20:40:33

标签: javascript html css

我正在开发一个网站,该网站具有几个过滤器按钮,这些按钮可分为几组。我试图找到一种方法来将这些按钮之一的类别设置为“ filter-set”,而组中的所有其他按钮都设置为“ not-set”。

每个按钮都是一个具有唯一ID的DIV。

我有一些肿的代码,其中每个按钮都有其自己的功能,并将关联的按钮设置为“未设置”,但这似乎效率不高,并且肯定有更好的方法!

膨胀的代码示例:

            function setClassR(){
                document.getElementById('filter_rare').className= 'filter-set';
                document.getElementById('filter_common').className= 'not-set';
                document.getElementById("filter_occasional").className = 'not-set';
                }
            function setClassC(){
                document.getElementById('filter_rare').className= 'not-set';
                document.getElementById('filter_common').className= 'filter-set';
                document.getElementById("filter_occasional").className = 'not-set';
                }
            function setClassO(){
                document.getElementById('filter_rare').className= 'not-set';
                document.getElementById('filter_common').className= 'not-set';
                document.getElementById("filter_occasional").className = 'filter-set';
                }

我希望能够为每组过滤器提供一个功能,当使用onClick=function()运行时,将单击的按钮设置为“过滤器设置”,将所有其他按钮设置为“未设置”

我尝试了以下代码,但似乎没有运行:

function setClassSeas(rareClass, commonClass, occClass) {
                      setClass("filter_rare", rareClass);
                      setClass("filter_common", commonClass);
                      setClass("filter_occ", occClass);

                    }

            function setClass(IDName, displayValue) {
              var items = document.getElementById(IDName);
              for (var i=0; i < items.length; i++) {
                items[i].className = (displayValue? "filter-set" : "not-set");
              }
            }

UPDATE ///

用作按钮的Divs的HTML代码:

    <div id="filter_rare" title="Rare" 
    class="not-set"   
    onclick="chosenFrequency('frequency=Rare'); setClassR();"></div>

    <div id="filter_common" title="Common" 
    class="not-set" 
    onclick="chosenFrequency('frequency=Common'); setClassC();"></div>

    <div id="filter_occasional" title="Occasional" 
    class="not-set" 
    onclick="chosenFrequency('frequency=Occasional'); setClassO();"></div>

3 个答案:

答案 0 :(得分:3)

如果每个按钮都有一个类,例如filter-button,则可以一次为所有按钮寻址。
在现代开发中,您应该attach an event handler而不是使用嵌入式 onclick 处理程序。

所有按钮具有共同的类,您可以一次找到它们。我正在更改按钮的外观,添加“ filter-button” 类并删除 onclick 处理程序:

<div id="filter_rare" title="Rare" 
     class="filter-button not-set">Rare</div>

(为了简化演示,我将文本放在div中)

现在收集所有过滤器按钮:

let filters = document.querySelectorAll('div.filter-button');

这将为您提供元素的 NodeList (有点像一个数组,但不是一个)。您需要将 onclick 事件处理程序附加到每个按钮。为此,您可以使用NodeList.forEach()调用。

filters.forEach(node => node.addEventListener('click', someFunction));

在单击按钮时调用的函数中,您要清除当前设置的任何filter-set类,放回原始的not-set类,然后设置filter-set类仅在单击的按钮上。这看起来像这样:

function someFunction(evt) {
    // again, use forEach to do the same thing to each filter button
    filters.forEach( function(node) {
        node.classList.remove('filter-set');
        node.classList.remove('not-set');
    } );
    // now add the 'filter-set' class on the button that was clicked
    evt.target.classList.add('filter-set');
}

使用classList而不是仅仅进行className="something"的好处是,classList可以添加/删除类,而无需考虑其他类。做className="something"会清除掉所有存在的类,并用“ something”代替它们。

将所有内容放在一起,并使用匿名函数而不是命名函数可以得到以下代码段:

let filters = document.querySelectorAll('div.filter-button');
filters.forEach(node => node.addEventListener('click',
            function(evt) {
                console.log(evt.target);
                filters.forEach(function(node) {
                    node.classList.remove('filter-set');
                    node.classList.add('not-set');
                });
                evt.target.classList.add('filter-set');
            }));
/* Make these look like buttons; put a green border on them */
.filter-button {
    min-height: 2ex;
    max-width: 12em;
    padding: .25em;
    margin: .7em .3em;
    background-color: lightgreen;
    border: 2px solid green;
    border-radius: 4px;
}

/* use a Red border on any button that has "filter-set" */
.filter-button.filter-set {
    border: 2px solid red;
}

/* limit the height of the stack-snippet console */
div.as-console-wrapper {
    max-height: 2.5em;
}
<div id="filter_rare" title="Rare" 
     class="filter-button not-set">Rare</div>

<div id="filter_common" title="Common" 
     class="filter-button not-set">Common</div>

<div id="filter_occasional" title="Occasional" 
     class="filter-button not-set">Occasional</div>

使用类not-set确实是多余的-默认情况下,您可以在按钮上没有额外的类,这样可以简化一些事情。按钮将具有filter-buttonfilter-button filter-set类。

答案 1 :(得分:1)

根据此更改您的setClass函数。希望它能工作。 document.getElementById()函数将始终返回单个元素(而不是元素列表)。即使您有多个具有相同ID的元素,此函数也将始终返回具有给定ID的第一个元素。不要忘记从html调用setClassSeas()函数。

function setClassSeas(rareClass, commonClass, occClass) {
    setClass("filter_rare", rareClass);
    setClass("filter_common", commonClass);
    setClass("filter_occ", occClass);
}

function setClass(IDName, displayValue) {
    var item = document.getElementById(IDName);
    item.className = displayValue ? "filter-set" : "not-set";
}
<div id="filter_rare" title="Rare" class="not-set"
    onclick="chosenFrequency('frequency=Rare'); setClassSeas(true, false, false);"></div>

<div id="filter_common" title="Common" class="not-set"
    onclick="chosenFrequency('frequency=Common'); setClassSeas(false, true, false);"></div>

<div id="filter_occasional" title="Occasional" class="not-set"
    onclick="chosenFrequency('frequency=Occasional'); setClassSeas(false, false, true);"></div>

答案 2 :(得分:-1)

这是另一种的方式(如“替代”)(但是使用jQuery,哦,不!)

$('body').click(function(e) {
  let $clicked = $(e.target);
  console.log("Clicked " + $clicked.attr('id'))

  if ($clicked.hasClass('filter')) {
    let $filters = $clicked.closest('.filter-group').find('.filter');
    let unset = $clicked.hasClass('set');
    $filters.toggleClass('not-set', true);
    $filters.toggleClass('set', false);
    if (!unset) {
      $clicked.toggleClass('not-set', false);
      $clicked.toggleClass('set', true);
    }
  }
})
button.filter.not-set {
  background: white;
}

button.filter.set {
  color: white;
  background: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="filter-group">
  <button id="filter_rare" class="filter not-set">
filter_rare
</button>
  <button id="filter_common" class="filter not-set">
filter_common
</button>
  <button id="filter_occasional" class="filter not-set">
filter_occasional
</button>
</div>

<div class="filter-group">
  <button id="filter_one" class="filter not-set">
filter_one
</button>
  <button id="filter_two" class="filter not-set">
filter_two
</button>
  <button id="filter_three" class="filter not-set">
filter_three
</button>
</div>