简体   繁体   中英

what is wrong with this javascript accordion code?

 var btn = document.querySelector('.btn'); var activePanel = document.querySelector('.active'); var hiddenPanel = document.querySelectorAll("section > div:not(.active)"); var i; for (i = 0; i < btn.length; i++) { btn[i].addEventListener("click", function() { var panel = this.nextElementSibling; var otherPanels = document.querySelectorAll("section > div:not(.active)"); panel.classList.add('.active'); otherPanels.classList.add('.hidden'); } }); };
 * { margin: 0; padding: 0; box-sizing: border-box; } .btn { color: white; background-color: brown; cursor: pointer; } .panel { display: none; } .active { display: block; } .hidden { display: none; }
 <body> <section id="accordion"> <h3 class="btn">button1</h3> <div class="panel">panel1</div> <h3 class="btn">button2</h3> <div class="panel">panel2</div> <h3 class="btn">button3</h3> <div class="panel">panel3</div> <h3 class="btn">button4</h3> <div class="panel">panel4</div> </section> </body>

Hello,

please I am trying to code a javascript accordion, but my code does not work

what I want to do is when I click on button, it shows its panel only by adding active class to this panel only and adding hidden class to all other panels at the same time

so when I click on button it toggles sliding up and down

and only one panel shows then when I click on other button it slide down its own panel and automatically slide up the other panel

please help and many thanks in advance

 var btn = document.querySelectorAll('.btn'); var activePanel = document.querySelector('.active'); var hiddenPanel = document.querySelectorAll("section > div:not(.active)"); var i; for (i = 0; i < btn.length; i++) { btn[i].addEventListener("click", function() { var panel = this.nextElementSibling; if (panel.classList.contains('active')) { panel.classList.remove('active'); panel.classList.add('hidden'); } else { var otherPanels = Array.from(document.querySelectorAll("section > div")); otherPanels.forEach(p => p.classList.add('hidden')); panel.classList.remove('hidden'); panel.classList.add('active'); } } ); }
 * { margin: 0; padding: 0; box-sizing: border-box; } .btn { color: white; background-color: brown; cursor: pointer; } .panel { display: none; } .active { display: block; } .hidden { display: none; }
 <body> <section id="accordion"> <h3 class="btn">button1</h3> <div class="panel">panel1</div> <h3 class="btn">button2</h3> <div class="panel">panel2</div> <h3 class="btn">button3</h3> <div class="panel">panel3</div> <h3 class="btn">button4</h3> <div class="panel">panel4</div> </section> </body>

Change your JavaScript code to the following:

var btn = document.querySelectorAll('.btn');
var activePanel = document.querySelector('.active');
var hiddenPanel = document.querySelectorAll("section > div:not(.active)");
var i;

for (i = 0; i < btn.length; i++) {
  btn[i].addEventListener("click", function() {
      var otherPanels = document.querySelectorAll("section > div");
      otherPanels.forEach(function (panel) {
        panel.classList.remove('hidden');
        panel.classList.remove('active');
      });


      var panel = this.nextElementSibling;
      console.log(panel);
      panel.classList.add('active');

      var otherPanels = document.querySelectorAll("section > div:not(.active)");
      otherPanels.forEach(function (panel) {
        panel.classList.add('hidden');
      });
    });
}

Code here: https://codepen.io/v08i/pen/RwNBJKN

var btn = document.querySelectorAll('.btn');
var activePanel = document.querySelector('.active');
var hiddenPanel = document.querySelectorAll("section > div:not(.active)");

var i;

for (i = 0; i < btn.length; i++) {
  btn[i].addEventListener("click", function() {
      var panel = this.nextElementSibling;
      var otherPanels = document.querySelectorAll("section > div.active");
        otherPanels.forEach((item) => {item.classList.remove('active');})
      panel.classList.add('active');


    }
  );

};

Don't use hidden class as you have already added " display:none " in .panel class , so you just need to remove and add active class

Adding to guys who already mentioned syntax errors and other fixes. You don't need any loops, array processings like in forEach and so on, and many event listeners for each button. Here is plain and simple solution with event listener on section:

let section = document.querySelector('#accordion');

section.addEventListener("click", function(event) {
  if(!event.target.classList.contains('btn')) return;

  let activePanel = section.querySelector('.active');
  let clickedPanel = event.target.nextElementSibling;

  clickedPanel.classList.add('active');
  activePanel && activePanel.classList.remove('active');
});

No loops, only one event listener, and you work only with one current element and one previously active (if any)!

Hope it helps

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