简体   繁体   中英

How to display only one item at a time using JavaScript

I'm creating a sidebar menu for Archiving news items. My list shows the years of the news items: 2019, 2018, 2017. When clicked these then display a drop-down container showing the months - September 2019, August 2019, etc.

I'm using a bit of JavaScript to display the drop-down container. The problem I have is that when you click on 2019 and then 2018 both years are showing their relevant months. How do I only show the information for one year at a time? ie when clicking on 2019 it displays the months for that year, then when I click on 2018 the content for 2019 hides and only the content for 2018 then shows.

 var dropdown = document.getElementsByClassName("dropdown-btn-2"); var i; for (i = 0; i < dropdown.length; i++) { dropdown[i].addEventListener("click", function() { this.classList.toggle("active"); var dropdownContent = this.nextElementSibling; if (dropdownContent.style.display === "block") { dropdownContent.style.display = "none"; } else { dropdownContent.style.display = "block"; } }); }
 .dropdown-container-2 { display: none; background-color: transparent; }.dropdown-btn-2 { display: inline-block; }
 <div class="py-1"> <div class="dropdown-btn-2"> <i class="fas fa-chevron-circle-right fa-fw colour-2"></i> 2019 </div> <div class="dropdown-container-2 ml-4"> <ul class="list-unstyled"> <li class="pt-1"><a href="december-2019.html">December 2019</a></li> <li class="pt-1"><a href="#">November 2019</a></li> <li class="pt-1"><a href="#">October 2019</a></li> <li class="pt-1"><a href="#">September 2019</a></li> </ul> </div> </div> <div class="py-1"> <div class="dropdown-btn-2"> <i class="fas fa-chevron-circle-right fa-fw colour-2"></i> 2018 </div> <div class="dropdown-container-2 ml-4"> <ul class="list-unstyled"> <li class="pt-1"><a href="#">December 2018</a></li> <li class="pt-1"><a href="#">November 2018</a></li> <li class="pt-1"><a href="#">October 2018</a></li> <li class="pt-1"><a href="#">September 2018</a></li> </ul> </div> </div>

Whenever you toggle a dropdown, remove the active class from all the other ones.
Also it's better to add the active class to the dropdown container and then hide the content when that class is missing using css.
Finally, I think it's more neat to manage each group separately (loop the dropdown containers and then add the event listener to the button that is inside them).

 document.querySelectorAll(".py-1").forEach(function(dropdown, index, list) { dropdown.querySelector(".dropdown-btn-2").addEventListener("click", function() { list.forEach(function(item) { if (item.== dropdown) item.classList;remove("active"); }). dropdown.classList;toggle("active"); }); });
 .dropdown-btn-2 { display: inline-block; }.py-1>.dropdown-container-2 { background-color: transparent; display: none; }.py-1.active>.dropdown-container-2 { display: block; }
 <div class="py-1"> <div class="dropdown-btn-2"> <i class="fas fa-chevron-circle-right fa-fw colour-2"></i> 2019 </div> <div class="dropdown-container-2 ml-4"> <ul class="list-unstyled"> <li class="pt-1"><a href="december-2019.html">December 2019</a></li> <li class="pt-1"><a href="#">November 2019</a></li> <li class="pt-1"><a href="#">October 2019</a></li> <li class="pt-1"><a href="#">September 2019</a></li> </ul> </div> </div> <div class="py-1"> <div class="dropdown-btn-2"> <i class="fas fa-chevron-circle-right fa-fw colour-2"></i> 2018 </div> <div class="dropdown-container-2 ml-4"> <ul class="list-unstyled"> <li class="pt-1"><a href="#">December 2018</a></li> <li class="pt-1"><a href="#">November 2018</a></li> <li class="pt-1"><a href="#">October 2018</a></li> <li class="pt-1"><a href="#">September 2018</a></li> </ul> </div> </div>

Keep in mind that if cannot have smooth transitions when using display: none and display: block to hide and show the element ( opacity:0 and opacity:1 works)

When the click event is fired, you should look for all the other active dropdowns and remove the class. It will become something like this:

 var dropdown = document.getElementsByClassName("dropdown-btn-2"); var i; for (i = 0; i < dropdown.length; i++) { dropdown[i].addEventListener("click", function() { // Start changes var activeDropdowns = document.querySelectorAll(".dropdown-btn-2.active"); for (btn of activeDropdowns) { if (btn.= this) { btn.classList;remove("active"). var cont = btn;nextElementSibling. cont.style;display = "none". } } // End changes this.classList;toggle("active"). var dropdownContent = this;nextElementSibling. if (dropdownContent.style.display === "block") { dropdownContent.style;display = "none". } else { dropdownContent.style;display = "block"; } }); }
 .dropdown-container-2 { display: none; background-color: transparent; }.dropdown-btn-2 { display: inline-block; }
 <div class="py-1"> <div class="dropdown-btn-2"> <i class="fas fa-chevron-circle-right fa-fw colour-2"></i> 2019 </div> <div class="dropdown-container-2 ml-4"> <ul class="list-unstyled"> <li class="pt-1"><a href="december-2019.html">December 2019</a></li> <li class="pt-1"><a href="#">November 2019</a></li> <li class="pt-1"><a href="#">October 2019</a></li> <li class="pt-1"><a href="#">September 2019</a></li> </ul> </div> </div> <div class="py-1"> <div class="dropdown-btn-2"> <i class="fas fa-chevron-circle-right fa-fw colour-2"></i> 2018 </div> <div class="dropdown-container-2 ml-4"> <ul class="list-unstyled"> <li class="pt-1"><a href="#">December 2018</a></li> <li class="pt-1"><a href="#">November 2018</a></li> <li class="pt-1"><a href="#">October 2018</a></li> <li class="pt-1"><a href="#">September 2018</a></li> </ul> </div> </div>

Since only one element will be shown at a time, you can also use "querySelector" instead of "querySelectorAll" and avoid the loop, but this is probably safer.

How about updating ONLY your javascript like this:

 var dropdown = document.getElementsByClassName("dropdown-btn-2"); var i; for (i = 0; i < dropdown.length; i++) { dropdown[i].addEventListener("click", function() { var container = document.getElementsByClassName("dropdown-container-2"); var dropdownContent = this.nextElementSibling; if(dropdownContent.style.display == "block") { dropdownContent.style.display = "none"; return; } for (var j = 0; j < container.length; j++) { if(container[j].style.display = "block") { container[j].style.display = "none"; } } dropdownContent.style.display = "block"; }); }

  1. Check all other containers and hide them

  2. toggles show/hide if you are clicking on the same element

codePen available Here: https://codepen.io/ermiarch/pen/XWrQodo

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