我正在开发一个网站,该网站具有几个过滤器按钮,这些按钮可分为几组。我试图找到一种方法来将这些按钮之一的类别设置为“ 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>
答案 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-button
或filter-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>