Search code examples
javascriptcssintersection-observer

classList.add() does not work inside setTimeout() function


I am using Intersection Observer to hide a div element when it is inside the viewport. For that purpose I am using setTimeOut() function to hide the div element after 2 seconds and using a nice CSS transition, but the classList.add() function does not seem to work inside the setTimeout() function in order to call the CSS transition to hide it.

This is my HTML where you can see the div element with id='sbox'. All sections have a height of 100vh.


  <body>
    <section id="page-1" class="primera"></section>

    <section id="page-2" class="segunda"></section>

    <section id="page-3" class="tercera">
      <div id="sbox" class="small-box"></div>
    </section>

    <script src="js/app.js"></script>
  </body>

this is my CSS:

.primera{
width: 100%;
height 100vh
}

.segunda {
  width: 100%;
  height: 100vh;
  background-color: #cbf3f0;
  background: linear-gradient(to bottom, #cbf3f0, #2ec4b6);
}

.tercera {
  width: 100%;
  height: 100vh;
  background-color: #5e60ce;
  display: grid;
  place-items: center;
  .small-box {
    width: 50%;
    height: 50%;
    opacity: 1;
    background-color: #ffbf69;
    transition: all 5s ease-out;
  }
}

.hide {
  transition: all 5s ease-out;
  opacity: 0;
}

This is my JS file:


let options = {
  root: null,
  threshold: 0.8,
};

function hideBox(entryArray) {
  let ibox = document.getElementById("sbox");

  if (entryArray[0].isIntersecting) {
    setTimeout(() => {
      console.log("hiding the first loading element");
      ibox.classList.add("hide");
    }, 2000);
  } else {
    ibox.classList.remove("hide");
  }
}

let observer = new IntersectionObserver(hideBox, options);
observer.observe(document.getElementById("page-3"));




Solution

  • since .tercera .small-box has a higher CSS specificity than .hide, the opacity in .hide is ignored

    Simplest solution is to add

    add

    &.hide {
      opacity: 0;
    }
    

    inside .small-box

    see the snippet

    let ibox = document.getElementById("sbox");
    
    setTimeout(() => {
      console.log("hiding the first loading element");
      ibox.classList.add("hide");
    }, 2000);
    .primera {
      width: 100%;
      height 3em;
    }
    
    .segunda {
      width: 100%;
      height: 3em;
      background-color: #cbf3f0;
      background: linear-gradient(to bottom, #cbf3f0, #2ec4b6);
    }
    
    .tercera {
      width: 100%;
      height: 3em;
      background-color: #5e60ce;
      display: grid;
      place-items: center;
      .small-box {
        width: 50%;
        height: 50%;
        opacity: 1;
        background-color: #ffbf69;
        transition: all 5s ease-out;
        &.hide {
          opacity: 0;
        }
      }
    }
    <section id="page-1" class="primera"></section>
    
    <section id="page-2" class="segunda"></section>
    
    <section id="page-3" class="tercera">
      <div id="sbox" class="small-box">a</div>
    </section>