JQuery: Flicker problem on Firefox with fadeOut and fadeIn

It has been a bloody nuisance getting the fadeIn and fadeOut to work properly on Firefox. I’ve been trying to get the content on the page to fade out, load new content and fade it in when the user clicks the navigation menu. But everytime I do that, there’s a flicker on the page that simply bugs the hell out of me.

After googling for half a day, I finally found out the reason. And it is not very straightforward, especially for someone getting into web design after a 6 year hiatus. Here’s what the problem is – Firefox gives you a vertical scrollbar on the side as long as you have content that extends beyond the vertical visual boundaries of your screen. But it doesn’t keep it there all the time. If the content can fit on your screen, it disappears. This causes the scroll bar to disappear when it’s not needed thereby making your layout move to the right because of the extra space.

Now apparently, there is some way to get the scroll bar to persist, but I couldn’t get it to work without having a double vertical scroll bar on the side. A number of options are available on this page, mainly in the comments, but none of them did the trick for me (I’m using Firefox 4).

So, back to googling and this time I came across this issue on the jquery website which says that fadeOut sets the display property to none and this causes an issue with the layout. More searching finally led to this mail chain in which one of the users suggests not to use fadeOut and fadeIn but rather just use animate() and that will solve the issue with the display:none. And it actually did. The annoying flicker is gone. Effectively, instead of using

$obj.fadeOut(‘slow’, function(){

$obj.fadeIn(‘slow’);

});

use:

$obj.animate({opacity:0}, ‘slow’, function(){

$obj.animate({opacity:1},’slow’);

});

and no more flickers! 🙂

 

Update: If you’d like to see a working POC, you can download the source here. It should work fine even with Javascript disabled.

Load in and Animate content with JQuery

I found out how to load and animate content using this excellent tutorial from tutsplus.com. But I wanted to take it one step further and also show the currently active link highlighted in the menu bar which took a bit of effort.

The full working sample can be downloaded from here.

Here’s the final version of the javascript:

$(document).ready(function(){

var hash = window.location.hash.substr(1);
var href = $(‘#nav li a’).each(function(){
var href = $(this).attr(‘href’);
if(hash==href.substr(0,href.length-5)){
var toLoad = hash+’.html #content’;
$(‘#content’).load(toLoad)
}
});

$(“.nav li a”).click(function(e){

var toLoad = $(this).attr(‘href’)+’ #content’;

var clickedMenuItem = $(this);//Store whatever you clicked over here

var currentMenuItem = $(this);//This is where you’ll store whatever is currently selected (in the next step)

$(“.nav li a”).each(function(){
if($(this).hasClass(“active”)){
currentMenuItem = $(this);//If it is active then set that to the currentMenuItem
return false;//Break out of the each() loop (http://gavinroy.com/jquery-tip-how-to-break-out-of-each)
}
return true;//Just to get rid of the warning “Function doesn’t always return a value”
});
e.preventDefault();
//Change animations to slideUp and slideDown to get the sliding animation
$(“#content”).fadeOut(‘slow’,function(){
$(“#content”).load(toLoad, function(){
$(“#content”).fadeIn(‘slow’);
});
});

window.location.hash = $(this).attr(‘href’).substr(0,$(this).attr(‘href’).length-5);
currentMenuItem.removeClass(“active”);//First remove and then add in case the same link is clicked
clickedMenuItem.addClass(“active”);

});

});