tags:

views:

1289

answers:

8

I'm getting an annoying "flickering" effect in Firefox when using jQuery "show" and "hide" on some div's. Any idea when this could be happening?

A: 

I've noticed this as well. I don't have a definite answer for you, but you might try tinkering with border/padding/margin for the element in question.

Ben Scheirman
+1  A: 

Two possible reasons:

  1. Hiding and showing is causing the scrollbar to appear and disappear, which changes the page width; or
  2. The div appearing and disappearing changes the width and/or height calculations.

Other than that, we'd need a sample.

cletus
+1  A: 

Depending on what you mean by flicker (if it only flickers when the page loads), instead of doing:

$(document).ready(function(){
   $("hide").hide();
});

<div id="hide">My Hidden Text</div>

Try adding display:none in the CSS:

<div id="hide" style="display:none">My Hidden Text</a>

CSS is applied to the DOM before even JavaScript is allowed to manipulate it, so if you do this, there should be no flicker when you load the page.

Also of note, in Firefox, there is a bug that causes the window to flicker when you change the size of the window (vertically), and the current scroll position is close or at the bottom of the window.

Stephen J. Fuhry
A: 

The flicker comes from this line of the jQuery code, in the show() method:

 var elem = jQuery("<" + tagName + " />").appendTo("body");

It does that to detect the CSS it should use for the display attribute, since different tags get different values (div: block, span: inline, tr: table-row, etc). Manipulating the DOM in this way causes the flicker.

Use:

jQuery('...').css('display','block');

which will generally do the same thing.

dbellizzi
+1  A: 

It is indeed this line that causes the flicker. I wrote this extension to remove the line from the show function. Note that it always sets the display element to 'block'.

I eventually solved it differently. I used a span element and changed it to a div.

/** fixes flicker in jQuery show function */
var fxAttrs = [
  // height animations
  [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
  // width animations
  [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
  // opacity animations
  [ "opacity" ]
 ];

function genFx( type, num ){
 var obj = {};
 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
  obj[ this ] = type;
 });
 return obj;
}

(function($){ 
    $.fn.extend({ 
 show: function(speed,callback){
  if ( speed ) {
   return this.animate(genFx("show", 3), speed, callback);
  } else {
   for ( var i = 0, l = this.length; i < l; i++ ){
    var old = jQuery.data(this[i], "olddisplay");

    this[i].style.display = old || "";

    if ( jQuery.css(this[i], "display") === "none" ) {
     jQuery.data(this[i], "olddisplay", 'block');
    }
   }

   // Set the display of the elements in a second loop
   // to avoid the constant reflow
   for ( var i = 0, l = this.length; i < l; i++ ){
    this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
   }

   return this;
  }
 }
    }); 
})(jQuery);
Wouter de Winter
A: 

@stephen It really works dude. I had the same problem and I tried it in IE and it works fine. Thanks..

Naveen
A: 

Per John Resig in reponse to a similar complaint on the Jquery Google Group here

Which browser? If you're in IE, then this flicker is because your page is in Quirks mode instead of Standards mode (you'll need to provide a correct DOCTYPE in order to trigger this).

Also this post seems to point to the same solution.

TooFat
+1  A: 

@Stephen: Hard-coding display: none in the CSS may seem like an easy fix, but it's potentially a bad idea. If the hidden content is important to the user, and simply being hidden on load for convenience (and is then displayed when the user, for example, clicks on a button), then display: none will permanently hide the content from those with javascript disabled. If accessibility is a concern for you then don't use this approach...

blindfish