How to fix double animation effect when using $(window).scroll function? - javascript

I'm trying to fix an issue whereas when the user scrolls, the elements in viewport already, starts triggering the animation a second time. This only happens when the page is loaded at the very top of the page then proceeding to scroll down. When positioned anywhere else on the page, it works fine and elements animate correctly and doesn't trigger twice in-view. To reiterate, the main issue is when the <section> tags animate, it'll animate again after page load when I scroll from the very top down, sort like a flashback initially, which I don't want. How do I fix this bug?
Here's the jsfiddle: https://jsfiddle.net/TheAmazingKnight/oybta7dp/10/
Code Attempt:
I tried something like this to do a check if these elements are already in view, dont trigger the animation until it has left view and reenters, but it doesn't work.
if ($(this).isInViewport()) {
if($(this).parent().hasClass("animate-section") && $(this).parent().hasClass("animate")) {
$(this).removeClass('animate-element');
$(this).removeClass('animate');
return false; // abort function if element is already in view preventing double animation
}
}
jQuery Code:
$(document).ready(function() {
var flag = true; // var to detect if function already ran once
if (flag) {
// Set the animation to be triggered when the section comes into view
var sections = $('.animate-section');
sections.each(function() { // check which sections are in-view on page load
if ($(this).isInViewport()) {
$(this).addClass('animate'); // Add the "animate" class to trigger the animation
} else {
$(this).removeClass('animate'); // Remove the "animate" class if the section is out of view
}
});
flag = false; // change boolean var as function already ran once
}
// Set the animation to be triggered when the element comes into view
var elements = $('.animate-element');
$(window).scroll(function() {
elements.each(function() {
if ($(this).isInViewport()) {
if($(this).parent().hasClass("animate-section") && $(this).parent().hasClass("animate")) {
$(this).removeClass('animate-element');
$(this).removeClass('animate');
//return false; // abort function if element is already in view preventing double animation
}
$(this).css("visibility", "visible");
$(this).addClass('animate'); // Add the "animate" class to trigger the animation
} else {
$(this).css("visibility", "hidden");
$(this).removeClass('animate'); // Remove the "animate" class if the section is out of view
}
});
});
});
// jQuery function to check if element is visible in viewport
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
EDIT:
Since this double animation effect only occurs at the top of the page, I added a code hack workaround for the time being. But if anyone can figure out a resolve would be great. Thanks!
$(document).ready(function () {
// code hack to scroll ever-so-slightly to trigger animating the elements only if initially loaded at the top of page to avoid double animation effect when user scrolls
if (window.scrollY == 0) {
Scrolldown();
}
});
// function to scroll ever-so-slightly
function Scrolldown() {
window.scroll(0, 1);
}

If I got it correctly, you want the animation for all the elements in the view when the page load, and then, just for the new ones while scrolling. I played around with your code and this is what I came up with.
/* CHAT PROMPT: Add some jQuery code where as when the user scrolls through the page, the section will animate as they come into view. */
$(document).ready(function() {
$('.animate-element').addClass("animate");
// Set the animation to be triggered when the element comes into view
var elements = $('.animate-element');
$(window).scroll(function() {
elements.each(function() {
if ($(this).isInViewport()) {
$(this).css("visibility", "visible");
$(this).addClass('animate'); // Add the "animate" class to trigger the animation
} else {
$(this).css("visibility", "hidden");
$(this).removeClass('animate'); // Remove the "animate" class if the section is out of view
}
});
});
});
// jQuery function to check if element is visible in viewport
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
I just removed that flag logic and added the "animate" class to all the element that should be animated at loading. When the scroll function is triggered, those elements already have the "animate" class, so they won't be animated again.
Here the jfiddle: https://jsfiddle.net/r25v7qot/1/

Related

Is there a way for changing different images at different scrolling point?

I'm trying to change one image at a time when I'm scrolling through the page.
This code actually changes all images classes when we get to that point of the scroll.
Is there any other way we can change images individually when scrolling?
Thank you.
jQuery(function($) {
var show = $(".show");
var hide = $(".hide");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if($(window).scrollTop() >= 500){
show.removeClass('show').addClass("hide");
hide.removeClass('hide').addClass("show");
} else {
show.removeClass("hide").addClass('show');
hide.removeClass('show').addClass("hide");
}
});
});
Since you're checking the scroll position of window and hiding/showing, this will hide/show all elements with the specified class name.
To achieve your purpose, add css position: relative to all images (if no position is specified already),
Then, iterate through each image as follows...
jQuery(function($) {
//var show = $(".show");
//var hide = $(".hide");
$(window).scroll(function() {
/*var scroll = $(window).scrollTop();
if($(window).scrollTop() >= 500){
show.removeClass('show').addClass("hide");
hide.removeClass('hide').addClass("show");
} else {
show.removeClass("hide").addClass('show');
hide.removeClass('show').addClass("hide");
}*/
var images = $('img');//or any other selector
$.each(images, function () {
if($(this).offset().top <= -500) {
$(this).hide();
}
else {
$(this).show();
}
});
});
});

jQuery scroll fade-in crash

This code works well, but when I scroll up and down after 4-5 times it crashes and all the elements disappear. Why does this happen and how do I fix it?
$(window).on("load",function() {
$(window).scroll(function() {
var winheight = $(window).innerHeight();
$(".fade").each(function() {
/* Check the location of each desired element */
var objectBottom = $(this).offset().top + $(this).outerHeight();
var windowBottom = $(window).scrollTop() + $(window).innerHeight();
/* If the element is completely within bounds of the window, fade it in */
if ( windowBottom > (objectBottom - (winheight*0.65))) { //object comes into view (scrolling down)
if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
}
});
}); $(window).scroll(); //invoke scroll-handler on page-load
});
Ok, I supposed that your html is something like this: https://jsfiddle.net/szdwwdac/
Sometimes, if you are scrolling fast up and down, when the element is fading out, your if doesn't work well.
if ( windowBottom >= (objectBottom - (winheight*0.65))) {
if ($(this).css("opacity")==0) {$(this).fadeTo(300,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(300,0);}
}
It's because of the 500ms of animation.
One of the solutions can be the eneble/disable for 500ms of the scroll page.
You can check this solution: How to disable scrolling temporarily?
EDIT
Another solution can be: add a class "fading" when you are inside your if. Then, in the if, eval if the element hasClass "fading". If not, you can go inside and make the animation.

Div stops at the top when scrolling

I am trying to make a div change class to fixed when it reach the top of the page.
I have this JavaScript code.
<script type="text/javascript">
$(function () {
var top = 200;
var y = $(this).scrollTop();
if (y >= top) {
// if so, add the fixed class
$('#kolonne-v').addClass('fixed');
} else {
// otherwise remove it
$('#kolonne-v').removeClass('fixed');
}
});
</script>
What am i doing wrong?
Demo jsFiddle
JS
$(function () {
var top = 200;
//this should be the offset of the top of your div
//which can be found by doing the following line
//var top = $("#kolonne-v").offset().top;
$(window).on('scroll', function () {
if (top <= $(window).scrollTop()) {
// if so, add the fixed class
$('#kolonne-v').addClass('fixed');
} else {
// otherwise remove it
$('#kolonne-v').removeClass('fixed');
}
})
});
Description
This uses the jquery .on('scroll', handler) method, documentation here. The basic principal is that on document.ready you set the scroll point when your div becomes fixed to the top. Then you setup an .on('scroll', handler) event that triggers whenever the window is scrolled in. If the user scrolls to your point you add the fixed CSS class.

Jquery when the user hits bottom of the page

I've been working on a scroll to top function for my website, and that part of it works fine. My problem is however that I have a fixed div that is overlapping my footer when it hits the bottom of the page.
Here is the function that I have working.
$(document).scroll(function (e) {
if (document.body.scrollTop >= 800) {
$('#beamUp').show(1000);
} else {
$('#beamUp').hide(1000);
return false;
}
});
Is there somehow I could detect when I hit that part of the page and stop the div from moving past that.Help is much appreciated!
jsFiddle: http://jsfiddle.net/zazvorniki/RTDpw/
Just get the height of the page, minus the height of the div in question, as well as the footer... make sure the top is never greater than that value... you'll also need an onresize event handler re-evaluate that value.
looking at your jsfiddle... here are my edits
In your scroll listener, I am checking for the position of the page, and adjusting the bottom position of the floater appropriately. I also set the initial display:none, so you don't need to call .hide() in your initial script. In addition, resizing the window has the effect of scrolling for your use, so I changed the listener for both events.
$(document).on('scroll resize', function (e) {
var viewHeight = $(window).height();
var viewTop = $(window).scrollTop();
var footerTop = $("footer").offset().top;
var baseline = (viewHeight + viewTop) - footerTop;
var bu = $("#beamUp").css({bottom: (baseline < 0 ? 0 : baseline) + 'px'});
if (viewTop >= 50) {
bu.show(1000);
} else {
bu.hide(1000);
}
});

jQuery slide a DIV out when scroll to anchor tag ~

I want to slide a DIV with contents out -- within a defined page area; within a long vertical 1 page website.
I have it setup with 6 DIV blocks;
Block 5 I have a CSS3 / jQuery animation wrapped in a DIV -- that I would like to SLIDE out into the page (from either left or right) with jQuery.
I'm thinking determining the point of slide from a defined anchor point; put within the the mark-up of the area that I'd like the DIV to slide into.
How could I write this;
..something like -- if anchor tag; SlideIn?
Something like;
slideLeftHide: function() {
return this.each(function() {
$(this).hide('slide', {direction: 'left'}, 1000);
});
http://jsfiddle.net/SZ8uH/2/
Try something like this:
var animInTriggeredAt = $("a#slidein").offset().top; //show when the anchor comes on stage
var animOutTriggeredAt = animInTriggeredAt + $(window).height(); //hide when it leaves the stage
var animActive = false;
// handle scroll event
$(window).scroll(checkScrollCues);
function checkScrollCues(){
var scrollY = $(window).scrollTop();
if (scrollY > animInTriggeredAt && scrollY < animOutTriggeredAt && !animActive){
animActive = true;
$("#myAnimatedDiv").show(); //put whatever animation code you want in here
} else if ((scrollY < animInTriggeredAt || scrollY > animOutTriggeredAt) && animActive){
animActive = false;
$("#myAnimatedDiv").hide(); //put whatever animation code you want in here
}
}

Categories

Resources