Just a quick question, complete novice when it comes to JavaScript but am learning! I have this code where when the elements have values of data-animate-in="fadeIn" data-animate-in-delay="100"
They fade in on scroll. That all works fine, the only problem I'm having is that they are now fading out when I scroll down the page... Is there a way I can have it so once it fades in the first time, it stays solid.
Here's my code
JavaScript
$(function() {
var html = $('html');
// On Screen
$.fn.isOnScreen = function() {
var elementTop = $(this).offset().top,
elementBottom = elementTop + $(this).outerHeight(),
viewportTop = $(window).scrollTop(),
viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
function detection() {
for (var i = 0; i < items.length; i++) {
var el = $(items[i]);
if (el.isOnScreen()) {
el.addClass("in-view");
} else {
el.removeClass("in-view");
}
}
}
var items = document.querySelectorAll(
"*[data-animate-in], *[data-detect-viewport]"
),
waiting = false,
w = $(window);
w.on("resize scroll", function() {
if (waiting) {
return;
}
waiting = true;
detection();
setTimeout(function() {
waiting = false;
}, 100);
});
$(document).ready(function() {
setTimeout(function() {
detection();
}, 500);
for (var i = 0; i < items.length; i++) {
var d = 0,
el = $(items[i]);
if (items[i].getAttribute("data-animate-in-delay")) {
d = items[i].getAttribute("data-animate-in-delay") / 1000 + "s";
} else {
d = 0;
}
el.css("transition-delay", d);
}
});
});
CSS
/* -- Animation -- */
[data-animate-in] {
opacity: 0;
transition: transform 0.8s ease, opacity 0.8s ease
}
[data-animate-in="up"] {
transform: translate3d(0, 24px, 0)
}
[data-animate-in="left"] {
transform: translate3d(-25%, 0, 0)
}
[data-animate-in="right"] {
transform: translate3d(25%, 0, 0)
}
[data-animate-in="down"] {
transform: translate3d(0, -24px, 0)
}
[data-animate-in="fadeIn"] {
transform: translate3d(0, 0, 0)
}
[data-animate-in].in-view {
opacity: 1;
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
transition: transform 0.6s ease, opacity 0.6s ease
}
.fade-in {
opacity: 0;
transition: opacity 1s ease
}
.page-loaded .fade-in,.page-loaded.fade-in {
opacity: 1
}
Any recommendations or improvement on my code, please let me know. Will be helpful as only just starting out!
Thanks :)
As stated in my comment I would recommend to remove the data-animate-in
attribute after the element has entered the viewport and the animation completes. Removing the attribute needs to be performed with a delay as the CSS rules also reference the attribute and removing it directly will make the element lose the CSS rules. This can be done via window.setTimeout()
:
if (el.isOnScreen()) {
el.addClass("in-view");
setTimeout(function() {
this.removeAttr('data-animate-in');
}.bind(el), 800);
} else {
el.removeClass("in-view");
}
I used 800 ms as delay as the CSS animation is also set to 0.8s:
transition: transform 0.8s ease, opacity 0.8s ease
If you want to change the duration please also change the delay to match the transition.
An updated Fiddle can be found here.