Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how to make element rotate on click

Im making an accordion and wonder how to make an arrow (lets suppose its an arrow svg icon) rotate 180deg once an accordion element is clicked and expanded in Vanilla JS?

Currently it only rotates the first element from the dom found that is matching my selected tag, because of querySelector and not querySelectorAll. How to use querySelectorAll properly in this case so not all of them get rotated?

document.querySelectorAll("details").forEach((accordion) => {
    accordion.addEventListener("click", () => {
      document.querySelectorAll("details").forEach((event) => {
        document.querySelector("details span").classList.add("active");
        if (accordion !== event) {
          event.removeAttribute("open");
        }
      });
    });
  });
summary{ 
  list-style: none 
}

details{
  padding: 1rem;
  background-color: lightblue;

 }

details summary{
  display: flex;
  justify-content: space-between;
}

details:nth-child(even){
  background-color: lightgreen;
}

p{
  padding-top: 0.3rem;
}

.active{
  transform: rotate(180deg);
}

span{
display: block;
}
<div>
  <details>
    <summary>    
      <h3>item1</h3> 
      <span>arrow</span> </summary>
    <p>desc1</p>
  </details>
  <details>
    <summary>
      <h3>item2</h3> 
      <span>arrow</span> 
    </summary> 
    <p>desc2</p>
  </details>
  <details>
    <summary> 
      <h3>item3</h3> 
      <span>arrow</span> 
    </summary>
    <p>desc3</p>
  </details>
</div>

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Once your accordion is clicked you are running a loop through all the accordions and performing actions. But you only need to look at the span which is child of the clicked accordion.

You can use this. this inside eventlistener callbacks always give the element on which event is attached. (You cannot use arrow functions with this). That is why I have converted them to non arrow functions.

I am following the same logic as yours but after removing from all the accordions, I am modifying the properties of the children of the current accordion. Have a look:

document.querySelectorAll("details").forEach((accordion) => {
    accordion.addEventListener("click", function () {
      document.querySelectorAll("details").forEach(function (elem) {
          elem.removeAttribute("open");
          elem.querySelector("span").classList.remove("active");
        }); this.querySelector("span").classList.add("active");

    });
  });
summary{ 
  list-style: none 
}

details{
  padding: 1rem;
  background-color: lightblue;

 }

details summary{
  display: flex;
  justify-content: space-between;
}

details:nth-child(even){
  background-color: lightgreen;
}

p{
  padding-top: 0.3rem;
}

.active{
  transform: rotate(180deg);
}

span{
display: block;
}
<div>
  <details>
    <summary>    
      <h3>item1</h3> 
      <span>arrow</span> </summary>
    <p>desc1</p>
  </details>
  <details>
    <summary>
      <h3>item2</h3> 
      <span>arrow</span> 
    </summary> 
    <p>desc2</p>
  </details>
  <details>
    <summary> 
      <h3>item3</h3> 
      <span>arrow</span> 
    </summary>
    <p>desc3</p>
  </details>
</div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading