Amja
Amja

Reputation: 1387

Animate element on page scroll

I have a header that I want to fade in when the user scrolls past the first section on the page. I use a div with opacity 0 which changes to opacity 1 like so:

$(window).scroll(function () {
  // If the scroll position is past the 1st section...
  if ($('body').scrollTop() > 500) {        
    $('#ribbon').css('opacity', 1);
  } else { 
    $('#ribbon').css('opacity', 0);
  }
});

This works fine but when I try to animate the opacity using either fadeIn() or animate(), it stops working and will not fade in the div.

Upvotes: 1

Views: 205

Answers (1)

Roko C. Buljan
Roko C. Buljan

Reputation: 206171

Avoid using style from within JS (unless really necessary, or difficult to achieve otherwise). Use instead .classList.toggle() (or .toggleClass() in jQuery). For a smoother transition (opacity i.e:) use transition: opacity 0.3s; for multiple properties comma separate the timings: transition: opacity 0.3s, background-color 0.3s;

Using JavaScript

const elRibbon = document.querySelector("#ribbon");

addEventListener("scroll", () => {
  const isShowRibbon = scrollY > 500;
  elRibbon.classList.toggle("is-visible", isShowRibbon);
}, { passive: true });
* { margin: 0; box-sizing: border-box; }

body {
  min-height: 300vh; /* just to force scrollbars */
}

#ribbon {
  padding: 2rem;
  background: #f00;
  position: fixed;
  width: 100%;
  opacity: 0;
  transition: opacity 0.3s;
}

#ribbon.is-visible {
  opacity: 1;
}
<div id="ribbon">Ribbon</div>
Scroll down past 500px to show ribbon!

Using jQuery

const $ribbon = $('#ribbon');

$(window).on("scroll", function() {
  const isShowRibbon = $(this).scrollTop() > 500;
  $ribbon.toggleClass("is-visible", isShowRibbon);
});
* {
  margin: 0;
  box-sizing: border-box;
}

body {
  min-height: 300vh; /* just to force scrollbars */
}

#ribbon {
  padding: 2rem;
  background: #f00;
  position: fixed;
  width: 100%;
  opacity: 0;
  transition: opacity 0.3s;
}

#ribbon.is-visible {
  opacity: 1;
}
<div id="ribbon">Ribbon</div>
Scroll down past 500px to show ribbon!

<script src="https://code.jquery.com/jquery-3.6.3.js"></script>

Avoid querying the DOM for elements inside a computationally expensive callback like on scroll. Instead cache the elements you want to manipulate beforehand into a variable like elRibbon and use it inside the callback.

Upvotes: 1

Related Questions