imnewhere
imnewhere

Reputation: 53

Show div when scrolling using vanilla JavaScript

I'm using vanilla JavaScript and would like to figure out a way where a div container is hidden, but when the user scrolls to 50% of the div container, that's when the div is fully visible. Kind of like a fading-in effect. This is what I have so far:

// delays scroll affects
function debounce(func, wait = 20, immediate = true) {
  var timeout;
  return function() {
    var context = this,
      args = arguments;
    var later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
}

// adds animation for section cards 
function cardActive(e) {
  const cards = document.querySelectorAll('.slide-in');
  // checks if image is half shown from bottom
  cards.forEach(card => {
    const slideInAt = (window.scrollY + window.innerHeight) - card.height / 2;
    if (slideInAt > card.offsetTop) {
      card.classList.add('active')
    } else {
      card.classList.remove('active');
    }
  })
};

window.addEventListener('scroll', debounce(cardActive));
.slide-in {
  opacity: 50%;
  transition: opacity 0.8s;
}

.slide-in.active {
  transition: opacity 0.8s;
  opacity: 100%;
  visibility: visible !important;
}

.placeholder {
  margin-top: 400px;
}

.icon {
  width: 100px;
}
<div class="placeholder"></div>

<div class="mission-1 slide-in">
  <div class="section-card">
    <img class="icon" src="https://image.flaticon.com/icons/svg/869/869767.svg" alt="icon">
    <h6 class="mission-card-title">Title 1</h6>
    <p class="p-special">Lorem Ipsum.</p>
  </div>
</div>

<div class="placeholder"></div>

Upvotes: 0

Views: 1387

Answers (2)

khajaamin
khajaamin

Reputation: 876

Here the image is already shown with opacity 1 and then once scrolled over it it will fade using just JS.

// adds animation for section cards 
window.addEventListener('scroll', (e) => {
  last_known_scroll_position = window.scrollY;
  let img = document.getElementById("img-1"); 
  if(img.offsetTop < last_known_scroll_position){
    img.style.opacity= 0.1;
  }else{
    img.style.opacity= 1;
  }

});
.slide-in {
  opacity: 50%;
}

.slide-in.active {
    opacity: 100%;
    -webkit-animation: animat_show 0.8s;
    animation: animat_show 0.8s;
    visibility: visible !important;
  }

.lorem {
  margin-bottom: 500px;
}

img {
  width: 500px;
}
<section class="space">
  <p class="lorem">lorem ipsum</p>
  <div class="slide-in">
    <img class="img-1" id="img-1" src="https://image.flaticon.com/icons/svg/869/869767.svg" alt="confetti">
  </div>
  <p class="lorem">lorem ipsum</p>
</section>

Upvotes: 0

Vasilis G.
Vasilis G.

Reputation: 7844

You need to make two small changes:

  1. You need to replace card.height with card.offsetHeight in your JS file.

  2. Use transition in your CSS file, you do not need animation for a fade in effect:

    .slide-in {
       opacity: 0%;
       transition: opacity 0.8s;
    }
    
    .active {
       transition: opacity 0.8s;
       opacity: 100%;
       visibility: visible !important;
    }
    

Upvotes: 1

Related Questions