Kagimura
Kagimura

Reputation: 417

alternative to nextElementSibling

I currently have a code that when a div is click, it add a style to the next div using nextElementSibling.

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    console.log(panel)
    if (panel.style.display === "block") {
      panel.style.display = "none";
    } else {
      panel.style.display = "block";
    }
  });
}
<div class="accordion">
  <p>Resources</p>
</div>
<div class=panel ">
 Test message
</div>

This add a style to the div with the class panel. I need to move the class accordion to the p tag instead of the div

like this:

<div>
  <p class="accordion">Resources</p> 
</div>
<div class= panel">
  Test message
</div>   

How do I target panel now that's accordion is no longer next to panel?

Upvotes: 1

Views: 1188

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337530

As the p is now child of the div which is a sibling to .panel, you can use parentElement to get back to that level of the DOM before using nextElementSibling, like this:

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.parentElement.nextElementSibling;
    
    if (panel.style.display === "block") {
      panel.style.display = "none";
    } else {
      panel.style.display = "block";
    }
  });
}
.panel { display: none; }
.active { color: #C00; }
<div><p class="accordion">Resources</p></div>
<div class="panel">Test message</div>

<div><p class="accordion">Resources</p></div>
<div class="panel">Test message</div>

<div><p class="accordion">Resources</p></div>
<div class="panel">Test message</div>

Also note that if you don't need to support IE you can use more modern methods to achieve the same JS logic more succinctly:

document.querySelectorAll('.accordion').forEach(el => {
  el.addEventListener('click', e => {
    let accordion = e.target;
    accordion.classList.toggle('active');
    accordion.parentElement.nextElementSibling.classList.toggle('show');
  });
});
.panel { display: none; }
.panel.show { display: block; }
.active { color: #C00; }
<div><p class="accordion">Resources</p></div>
<div class="panel">Test message</div>

<div><p class="accordion">Resources</p></div>
<div class="panel">Test message</div>

<div><p class="accordion">Resources</p></div>
<div class="panel">Test message</div>

Upvotes: 1

Related Questions