Aurore
Aurore

Reputation: 746

Toggle class and remove from other elements using a filter

I'd like to toggle between classes on a page with two sections : when you click the first one, it toggle a class called open and removes it from the other section that eventually had it.

I've managed to make things work with the toggle, but the other section has not the class open removed. So I started experimenting with the .filter but I can't manage to understand it...

The behaviour: only one div should be red at the same time

document.addEventListener("DOMContentLoaded", function(e) {
const sections = document.getElementsByTagName("section");

Array.from(sections).forEach(function(section) {
    section.addEventListener('click', function(el) {
        //console.log(sections, el)
        //var diff = sections.filter(element => element !== section)
        //console.log(diff)
        section.classList.toggle("open")
    });
  });
  
});
body{
    margin: 0;

}

main{
    width: 100%;
    display: flex;
    justify-content: center;
    flex-direction: row;   
}

section{
    transition: all 300ms ease-in-out;
    padding-top: 2em;
    flex-grow: 2;
    flex-basis: 0;
    display: flex;
flex-direction: column;
}

section:nth-child(1){
    background-color: lightblue;
}

section:nth-child(2){
    background: rgb(137, 110, 148);
}

section.open{
    background: red;

}

img{
    width: 90%;
    align-self: center;
}
<main>
    <section class="left" id="swup" >
        <img src="https://picsum.photos/200/300" alt="">
    </section>
    <section  class="right" id="swup" >
        <img src="https://picsum.photos/200/400" alt="">
</section>

</main>

Upvotes: 2

Views: 803

Answers (2)

Andy
Andy

Reputation: 63589

Instead of using toggle consider using add and remove on the class list instead. No need for filter.

// Cache the sections
const sections = document.querySelectorAll('section');

// Add listeners to them
sections.forEach(section => {
  section.addEventListener('click', handleClick);
});

// Remove the open classes from all the sections first
// and then add one to the section that was clicked
function handleClick() {
  sections.forEach(section => section.classList.remove('open'));
  this.classList.add('open');
}
main,section{display:flex}body{margin:0}main{width:100%;justify-content:center;flex-direction:row}section{transition:.3s ease-in-out;padding-top:2em;flex-grow:2;flex-basis:0;flex-direction:column}section:first-child{background-color:#add8e6}section:nth-child(2){background:#896e94}section.open{background:red}img{width:90%;align-self:center}
<main>
  <section class="left" id="swup">
    <img src="https://picsum.photos/200/300" alt="">
  </section>
  <section class="right" id="swup">
    <img src="https://picsum.photos/200/400" alt="">
  </section>
</main>

Upvotes: 2

GrafiCode
GrafiCode

Reputation: 3374

You were on the right track with filter() you just forgot to convert sections to Array first.

document.addEventListener("DOMContentLoaded", function(e) {
const sections = document.getElementsByTagName("section");

Array.from(sections).forEach(function(section) {
    section.addEventListener('click', function(el) {
        //console.log(sections, el)
        var diff = Array.from(sections).filter(element => element !== section)
        diff.forEach(function(otherEl) {
          otherEl.classList.remove("open")
        })
        section.classList.toggle("open")
    });
  });
  
});
body{
    margin: 0;

}

main{
    width: 100%;
    display: flex;
    justify-content: center;
    flex-direction: row;   
}

section{
    transition: all 300ms ease-in-out;
    padding-top: 2em;
    flex-grow: 2;
    flex-basis: 0;
    display: flex;
flex-direction: column;
}

section:nth-child(1){
    background-color: lightblue;
}

section:nth-child(2){
    background: rgb(137, 110, 148);
}

section.open{
    background: red;

}

img{
    width: 90%;
    align-self: center;
}
<main>
    <section class="left" id="swup" >
        <img src="https://picsum.photos/200/300" alt="">
    </section>
    <section  class="right" id="swup" >
        <img src="https://picsum.photos/200/400" alt="">
</section>

</main>

Upvotes: 2

Related Questions