Fade in and out bug with jQuery - javascript

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>

Related

Fix delayed jquery fade on scroll

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.

How do I implement return false; into JavaScript if/else

I'm trying to construct a nav bar that changes from height:'70px' to height:'50px' when the page is scrolled away from the top, and then changes back to height:'70px' whenever the page is scrolled back to the top.
To achieve this I've tried this code:
// JavaScript Document
$(document).ready(function() {
$(window).scroll(function () {
var scroll_top = $(this).scrollTop();
if (scroll_top > 0){
$('nav').animate({
height:'50px'
});
}else{
$('nav').animate({
height:'70px'
});
}
});
});
What happens with this code is that the page loads correctly, and the first time I scroll down the height animates fine. However, whenever I scroll back to top it either won't change back to height:'70px', or (and this last part happens a lot when I try to animate additional values such as width or opacity) the entire nav bar looks to be flickering as if it were caught in a loop.
I spoke to a programmer yesterday who said it sounded like the page was re-firing .animate any time the pixel value of the nav bar changed while animating, creating an infinite loop. He suggested I implement a return false; condition to remedy this, but I'm unsure how exactly to implement it. Any help?
Suggestions on how do achieve this same effect in a different, more effective manner would also be appreciated.
Make it a lot simpler:
Have some CSS:
nav {
height:50px;
transition:height 0.4s ease;
}
nav.scrolledFromTop {height:70px}
Now your jQuery:
$(window).scroll(function() {
$("nav")[this.scrollTop > 0 ? "addClass" : "removeClass"]("scrolledFromTop");
});
Done! That is the magic of CSS3 ;)

Jquery auto sliding lists

I have here a slider, built only with HTML and CSS, but it's not auto sliding.
I thought maybe some Jquery will help.
I have a Fade In, Fade Out function but it it's turning the black background while it's changing. And I don't like that!
function InOut(elem) {
var delayOn = 3000, // time each <li> should be visible
delayOff = 0, // time between revealing each <li>
fade = 1000; // fade duration
// Pause, fade in, pause again, fadeout, then fire the callback
elem.delay(delayOff).fadeIn(fade).delay(delayOn).fadeOut(function() {
// If we're not on the last <li>
if (elem.next().length > 0) {
// Call InOut on the next <li>
InOut(elem.next());
}
else {
// Else go back to the start
InOut(elem.siblings(':first'));
}
});
}
$(function() {
// Hide all the li's
$('#slider li').hide();
// Call InOut to loop through them
InOut($('#slider li:first'));
});
Please look at this JSFiddle and let me know how I can do this, a sliding animation will work also, thanks!
PS: If you want to look how is sliding only with CSS, just delete de JS function!
If I understand your question correctly, this may be a solution for you:
Demo Fiddle
It looks like your #slideshow-inner CSS has the background set to black, simply change it to the color you want.
CSS:
#slideshow-inner {
//current styles
background-color: rgba(255,255,240,1);
}

Jquery Slideshow Animations Behaving Strangely (events firing, building up in queue)

I am trying to create a very simple slideshow.
I would like the slideshow to pause on hover and resume when the user moves their mouse off the slideshow (#slide_container). While the slideshow works fine, and so does the hover (to an extent), if I flick my mouse on and off the slideshow repeatedly, it completely messes the slide and starts animating sporadically (check the fiddle below to see what I mean).
I tried adding promise, so that before animating it completes any queued animation, but despite this, the behaviour remains.
How should I go about fixing this?
Here is the fiddle: http://jsfiddle.net/hR6wZ/
my js code:
$(document).ready(function() {
//get variables
var slide_width = $('.slider_container').width();
var number_of_slides = $('.slider_container .slide').length;
var slider_width = slide_width*number_of_slides;
//set element dimensions
$('.slide').width(slide_width);
$('.slider').width(slider_width);
var i = 0;
var hover_switch = 0;
$('.slider_container').hover(function() {
//Hover mode on
hover_switch = 1;
}, function() {
//Hover mode off
hover_switch = 0;
sliderLoop()
});
function animateSlider() {
$(":animated").promise().done(function() {
$('.slider').finish().animate({ marginLeft: -(slide_width * i) });
});
}
function sliderLoop() {
setTimeout(function(){
//Only runs if hover mode is off;
if(i < number_of_slides-1 && !hover_switch) {
i++;
animateSlider();
sliderLoop();
}
else if (!hover_switch)
{
i = 0;
animateSlider();
sliderLoop()
}
},4000);
}
sliderLoop();
});
EDIT: also I did try using stop instead of finish() but this didn't fix the issue..
Becuase your calling the slider loop each time you hover out everytime even if you hover back and forth like ten times it tells it and queus it up to animate the x amount of times you did that.
What you can try is Only have the slider loop check right then and their when it's about to animate if it is being hovered or not and don't call the slider loop from the every time that it hovers out.
Another way is right before it begins animating set a variable for the duration of the animation to tell it not to call the animateSlider function if Currently_animating
so add && !currently_animating to each if statement within the sliderloop function.
That method however will help but probably the first way would be better as then it will never animate more then every x miliseconds or however long you set it to be.
But in General you probably should not call the sliderloop function if hover_switch = 0 becuase then it will just queue up the slider loop each time you hover out.

Getting bottom scroll.y when scrolling to the bottom

I'm using a nicescroll a plugin that I use to create scrollbars on divs.
$('#postscroller').niceScroll();
var nice = $("#postscroller").getNiceScroll()[0];
$('#postscroller').bind("scroll",function()
{
if(nice.scrollvaluemax==nice.scroll.y)
{
alert('bottom');
}
alert(nice.scroll.y);
});
First I activate the div to be scrolled.
Then I save the nicescroll instance to the nice variable.
When I test the scroll event to see wether the scroll.y is being fired when I scroll to the bottom I get some numbers but not 134 which is nice.scrollvaluemax in the div I'm testing.
I do get however 134 when I'm at the bottom and I scroll upwards.
Any idea on how can I get 134 when scrolling to the bottom?
Thanks
you get other numbers because you are not at the bottom when you scroll down...
probably related to your current position when the scroll is fired.
post more code.
I fixed it by calling this at the scroll event
var postscrollertimer = (function() {
var timer;
return function() {
clearTimeout(timer);
timer = setTimeout(function()
{
if(postscroller.scrollvaluemax==postscroller.scroll.y)
{
//do stuff
}
}, 1000);
};
})();

Categories

Resources