简体   繁体   中英

JavaScript: toggle button group not working correctly

I tried to implement a toggleable button group into my popup window. It works kinda... but not fully. Heres the code, it is kinda complicated to explain so please enable all buttons in the snippet and then you will see. And yea, i know. The code is very unoptimised, just tried to make it work. Thanks for any help! :)

 document.getElementById("off1").addEventListener("click", function() { if(document.getElementById("off1")) { document.getElementById("off1").id = "on"; } else { document.getElementById("on").id = "off1"; } }); document.getElementById("off2").addEventListener("click", function() { if(document.getElementById("off2")) { document.getElementById("off2").id = "on"; } else { document.getElementById("on").id = "off2"; } }); document.getElementById("off3").addEventListener("click", function() { if(document.getElementById("off3")) { document.getElementById("off3").id = "on"; } else { document.getElementById("on").id = "off3"; } }); document.getElementById("off4").addEventListener("click", function() { if(document.getElementById("off4")) { document.getElementById("off4").id = "on"; } else { document.getElementById("on").id = "off4"; } }); document.getElementById("off5").addEventListener("click", function() { if(document.getElementById("off5")) { document.getElementById("off5").id = "on"; } else { document.getElementById("on").id = "off5"; } }); document.getElementById("off6").addEventListener("click", function() { if(document.getElementById("off6")) { document.getElementById("off6").id = "on"; } else { document.getElementById("on").id = "off6"; } }); document.getElementById("off7").addEventListener("click", function() { if(document.getElementById("off7")) { document.getElementById("off7").id = "on"; } else { document.getElementById("on").id = "off7"; } }); document.getElementById("off8").addEventListener("click", function() { if(document.getElementById("off8")) { document.getElementById("off8").id = "on"; } else { document.getElementById("on").id = "off8"; } }); 
 input { width: 95px; float:left; font-size: 12px; border-radius: 2px; margin: 5px; padding: 3px; } #off1, #off2, #off3, #off4, #off5, #off6, #off7, #off8 { background-color: #101820FF; color: #fff; border:1px solid white; } #on { background-color: #FEE715FF; color:#101820FF; border: 1px solid #FEE715FF; } 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="../css/popup.css"> </head> <body> <div class="item-toggle-group"> <input type="button" id="off1" value="jackets"> <input type="button" id="off2" value="shirts"> <input type="button" id="off3" value="tops/sweaters"> <input type="button" id="off4" value="sweatshirts"> <input type="button" id="off5" value="pants"> <input type="button" id="off6" value="hats"> <input type="button" id="off7" value="bags"> <input type="button" id="off8" value="accessories"> <script src="../js/toggleButton.js"></script> </div> </body> </html> 

Use a data attribute to identify if a button is on and classes to identify the buttons.

Html

<input type="button" class="button" value="jackets" data-on="0">
<input type="button" class="button" value="thing2" data-on="0">
<input type="button" class="button" value="thing3" data-on="0">
<input type="button" class="button" value="thing4" data-on="0">
<input type="button" class="button" value="thing5" data-on="0">

Javascript

document.getElementsByClassName("button").addEventListener("click", function() {
    if(this.getAttribute("data-on") == "1") {
        this.setAttribute("data-on", "0");
    } else {
        this.setAttribute("data-on", "1");
    }
});

CSS

.button {
  ... css for buttons that are off
}

.button[data-on=1] {
  ... css for buttons that are on
}

Using classes makes it generic so you can just add buttons on the fly without adding an event listener for that specific button.

You should not be modifying the ID of your button elements - once two are turned on, you have two elements with the same ID of 'on'. At this point, when you turn any of them off, only the first element with the ID of 'on' is being set back to the off state (not necessarily the one you clicked to turn off).

Easiest fix is to modify the class of these button elements (not the ID) using:

document.getElementById("off5").className = "on";

Then also change your CSS to style by class, not by ID

.on { /* styles here */  }

not

#on { /* styles here */ }

Use classes instead. Then you only need one function. When you click a button remove the on class from all the elements and then add it to this element

 function highlight() { items.forEach(function(item) { item.classList.replace('on', 'off'); }); this.classList.replace('off', 'on'); } var items = document.querySelectorAll(".off"); items.forEach(function(item) { item.addEventListener("click", highlight); }); 
 input { width: 95px; float:left; font-size: 12px; border-radius: 2px; margin: 5px; padding: 3px; } .off { background-color: #101820FF; color: #fff; border:1px solid white; } .on { background-color: #FEE715FF; color:#101820FF; border: 1px solid #FEE715FF; } 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <div class="item-toggle-group"> <input type="button" class="off" value="jackets"> <input type="button" class="off" value="shirts"> <input type="button" class="off" value="tops/sweaters"> <input type="button" class="off" value="sweatshirts"> <input type="button" class="off" value="pants"> <input type="button" class="off" value="hats"> <input type="button" class="off" value="bags"> <input type="button" class="off" value="accessories"> </div> </body> </html> 

Instead of id you can use class so that you can use classList.toggle method to toggle on class on specific button click.

 document.querySelectorAll('.toggle').forEach(function(button) { button.addEventListener('click', function() { this.classList.toggle('on'); }) }) 
 input { width: 95px; float: left; font-size: 12px; border-radius: 2px; margin: 5px; padding: 3px; } .toggle { background-color: #101820FF; color: #fff; border: 1px solid white; } .on { background-color: #FEE715FF; color: #101820FF; border: 1px solid #FEE715FF; } 
 <div class="item-toggle-group"> <input type="button" id="off1" class="toggle" value="jackets"> <input type="button" id="off2" class="toggle" value="shirts"> <input type="button" id="off3" class="toggle" value="tops/sweaters"> <input type="button" id="off4" class="toggle" value="sweatshirts"> <input type="button" id="off5" class="toggle" value="pants"> <input type="button" id="off6" class="toggle" value="hats"> <input type="button" id="off7" class="toggle" value="bags"> <input type="button" id="off8" class="toggle" value="accessories"> </div> 

To remove on class on sibling elements you can create one function that will return sibling nodes of clicked element and remove on class from each of those sibling nodes.

 function getSiblings(el, nodes) { return [...nodes].filter(node => node != el) } document.querySelectorAll('.toggle').forEach(function(button) { button.addEventListener('click', function() { this.classList.toggle('on'); getSiblings(this, this.parentNode.children).forEach(function(button) { button.classList.remove('on'); }) }) }) 
 input { width: 95px; float: left; font-size: 12px; border-radius: 2px; margin: 5px; padding: 3px; } .toggle { background-color: #101820FF; color: #fff; border: 1px solid white; } .on { background-color: #FEE715FF; color: #101820FF; border: 1px solid #FEE715FF; } 
 <div class="item-toggle-group"> <input type="button" id="off1" class="toggle" value="jackets"> <input type="button" id="off2" class="toggle" value="shirts"> <input type="button" id="off3" class="toggle" value="tops/sweaters"> <input type="button" id="off4" class="toggle" value="sweatshirts"> <input type="button" id="off5" class="toggle" value="pants"> <input type="button" id="off6" class="toggle" value="hats"> <input type="button" id="off7" class="toggle" value="bags"> <input type="button" id="off8" class="toggle" value="accessories"> </div> 

I'd recommend using element.classList.toggle('toggle-class')

 function doToggle(event) { event.target.classList.toggle('toggled'); } var toggleInputs = document.getElementsByTagName('input'); for(var index in toggleInputs) { toggleInputs[index].onclick = doToggle; } 
 .toggled { background: green; } 
 <input type="button" value="toggle me 1"><br> <input type="button" value="toggle me 2"><br> <input type="button" value="toggle me 3"><br> <input type="button" value="toggle me 4"><br> <input type="button" value="toggle me 5"><br> <input type="button" value="toggle me 6"><br> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM