vol7ron showed me how to achieve an effect where an element fades in on scroll down, and fades out on scroll up here: Why does "($(this).css('opacity')==.3)" not work?
jsfiddle: http://jsfiddle.net/b7qnrsrz/16/
$(window).on("load", function () {
function fade() {
$('.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 object is completely visible in the window, fade it in */
if (objectBottom < windowBottom) { //object comes into view (scrolling down)
if ($(this).css('opacity') != 1) {
$(this).stop(true,false).fadeTo(500, 1);
}
} else { //object goes out of view (scrolling up)
if ($(this).css('opacity') == 1) {
$(this).stop(true,false).fadeTo(500, .3);
}
}
});
}
fade(); //Fade in completely visible elements during page-load
$(window).scroll(function () {
fade();
}); //Fade in elements during scroll
});
This works almost perfectly. As is, the boxes wait to fade until I've stopped scrolling. So if I smoothly scroll past three of them, rather than fading one-by-one as I scroll past each one, they all wait to fade in until after I stop scrolling. How can I remedy this so that fade triggers even while scrolling, not waiting until after stopping?
That's because there is a bug in the script.
Every time you scroll it executes the fade function. Because the animation is prefixed with a stop() the animation never really gets any time to run if you scroll slowly.
You can either remove the .stop() or find a way to only apply the fade-in to elements that are not already fading in.
There seems to be another bug. Sometimes items are not detected as being in the viewport and they will not fade in. I'm not sure why that happens. It might have something to do with scrolling really fast.
Related
My problem is, that after fast scrolling down with the touchpad, the window is correctly jumping to the top after 300px, but after that, the browser is stil scrolling down.
Here is a example of my problem
https://codepen.io/anon/pen/XoMExW
I´ve tried this, but it didn´t work
How to disable scrolling temporarily?
$(window).scroll(function(){
if( $(window).scrollTop() >= 300 ){
$(window).scrollTop(0);
}
});
What you could do is after each scroll event, add a setTimeout. For every scroll event, you will first clear the one you created in the previous event and recreate a new one right after. This will keep running until you reach the last scroll event, then during this last scroll event, the callback of the setTimeout will be triggered and it will run your code:
var isScrolling;
$(window).scroll(function() {
window.clearTimeout(isScrolling);
isScrolling = setTimeout(function() {
if ($(window).scrollTop() >= 300) {
$(window).scrollTop(0);
}
}, 100);
});
this is my simple scroll function.
When user scrolls a certain distance from the bottom of the page, a registration box appears via animation:
$(window).scroll(function(){
if($docHeight - $top < 500 && document.cookie.indexOf("flag") < 0) {
$('.register').stop().animate({
'bottom': -1,
});
return false;
}
});
My problem is that the .stop() function before .animate() triggers every time the user scrolls; and so during animation it is constantly stopping as the user scrolls causing a 'juddering' effect (of course, no juddering if the user doesn't scroll).
I have thought about setting flags during animation and not running the animation to avoid this, but I can't figure it out.
I believe the function .once() could be used well here?
Thanks
I've build a sticky navigation that disappears when the user scrolls down, and re-appears when he/she scrolls back up. This is so there's more content visible on smaller screens when, for example, reading an article.
The problem I had was animations queue build-up, but I was able to fix it using .stop()
However, this created another problem, which is no smooth animations. When you keep scrolling up, the .stop() gets executed, and then the scroll-up animation continues, creating a weird animation effect.
$(document).ready(function() {
$(window).load(function() {
var $menu = $('.mobile-menu');
var previousTop = $menu.offset().top;
$(document).scroll(function() {
// Determine scroll position
var top = $(this).scrollTop();
// Check if user is scrolling up
if (top < previousTop) {
// .stop() prevents animation queue build-up
$menu.animate({
top: 0
}, 200);
}
else {
// .stop() prevents animation queue build-up
$menu.animate({
top: -$menu.outerHeight()
}, 200);
}
previousTop = top;
});
});
});
Fiddle: http://jsfiddle.net/8wwtLda3/
I know I can fix this using CSS transitions, but the script has to be reusable, and editing the CSS files isn't always an options.
Any tips on how to get smooth jQuery animations, without a queue building up?
SOLUTION: Thanks to Fonzy for telling me about .queue() I was able to fix this.
http://jsfiddle.net/8wwtLda3/1/
I have made a function wich runs on the computer very well. But on mobiles the position refreshes only when the scrolling stops. Its a known problem and i found answers but I didnt get it in my function working. Maybe one of you can help me.
my function:
$(window).scroll(function () {
if ($(window).scrollTop() >600) {
$('#logo').css('position', "fixed");
$('#logo').css('top', 0);
}
else if($(window).scrollTop() < 600) {
$('#logo').css('position', "relative");
$('#logo').css('top', 600)
}
});
and in the internet i found this which i should replace in my function:
$('body').on({
'touchmove': function(e) {
console.log($(this).scrollTop()); // Replace this with your code.
}
});
or this:
$('body').bind('touchmove', function(e) {
console.log($(this).scrollTop()); // Replace this with your code.
});
It would be nice if someone could rewrite my function so that it works smoothly on mobiles.
I explain shortly what this function do. When you load my page there is a blackscreen with a headline in the middle of the screen. Nothing else. when you scroll down the title should move up normaly until he reaches the top. when it reaches the top it gets the "position: fixed" attribute. when you scroll up it gets the "position: relative" attribute again. Nothing else should happen. But on mobiles the text scrolls up until the scrolling stops (most of the time you scroll the text out of the screen) and pop up on the fixed position. But when it is fixed everything is ok and it stands there.
On my page, when the user gets to say 1000 pixels scrolled down the page, my navigation fades out, when i scroll back up the navigation fades in. Im using the following which works perfectly...
// Fade Navigation
if(!$('nav ul').is(':visible')) {
$('nav ul').stop().fadeIn(500);
} else {
$('nav ul').stop().fadeOut(500);
}
My only problem is that if you scroll really quickly, the animation doesnt know if its visible or not, is there a way to stop this?
If you pass in true as a second parameter to .stop(), it'll stop the animation and jump the element to the state it should be in if the animation actually finished.
i.e. if you call $('nav ul').stop(true, true).fadeIn(500) while an element is fading out, it will stop the fade out, and make it jump to it's logical end (which is completely faded out) before starting the .fadeIn() animation.
Using that, you should be able to get away with the following instead of your code block above:
$('nav ul').stop(true, true).fadeToggle(500);
It'll look a little jerky though, but you can work around it with a bit more complicated logic.
I've been playing around with this. See comments in code.
<nav class="main">
<ul>
<li>One</li>
<li>Two</li>
</ul>
</nav>
<script type="text/javascript">
// Do this outside of the onscroll handler. onscroll is fired a lot,
// so performance will slow if you're having to create jq instances
// or navigate the dom several times
var $wnd = $(window);
var $nav = $('nav.main');
// Added this to block the main handler from executing
// while we are fading in or out...in attempt
// to smooth the animation
var blockHandler = false;
window.onscroll = function () {
if (!blockHandler) {
blockHandler = true;
// I've used 50 here, but calc the offset of your nav
// and add the height to it. Or, maybe just half the
// height to it so you can see the animation.
if ($wnd.scrollTop() < 50) {
$nav.fadeIn(500, function () {
blockHandler = false;
});
} else {
$nav.fadeOut(500, function () {
blockHandler = false;
});
}
}
};
</script>