1

Can anyone explain to me what is happening here?

I am trying to use jQuery to center wizard elements on a page. The first time showCentered() is called on an element, it is correctly centered on the page and all looks good. The second time however the element is shifted way off to the side (and not exactly double the previous values either).

SO the first time it's called it works fine. The second (and third, .. etc) times it gets shifted farther and farther off the page.

Example Code:

function showCentered(selector){
          d         = $(selector);
            h       = d.outerHeight();
            w       = d.outerWidth();
            hMax    = $(window).height();
            wMax    = $(window).width();

            _top    = (hMax / 2) - (h / 2);
            _left   = (wMax / 2) - (w / 2);

            if (_left < 0) _left = 0;
            if (_top < 0) _top = 0;

            d.offset({
                top:    _top,
                left:   _left
            });

        d.show();
}

//1st time, OK 
$('.demo').hide();
showCentered('.demo');

//2nd time, NOT OK
$('.demo').hide();
showCentered('.demo');

Here is a working demo of the above: Codepen.io

When running the above function for the .demo element I get the following values for h, w, hMax, wMax, _top, _left, and then offset().top, offset().left. Notice how the offset values changes the second time around.

Also of note is that this will affect any element that uses offset after the first time around.

Can anyone explain why offset is shifting after each use?

cwbit
  • 88
  • 1
  • 6

1 Answers1

3

You cannot reliably get the dimensions of a hidden element.

See jQuery outerHeight for hidden element

jQuery attempts to compensate, but you can sometimes still end up with incorrect values. See jQuery: height()/width() and "display:none"

EDIT: Actually the real problem is $.offset() cannot be used to correctly set the position of a hidden element. It attempts to do calculations based on the current location of the element in relation to its offset parent and these calculations are just wrong if the element is hidden. Just move d.show(); to just before you set the offset fixes the problem.

Community
  • 1
  • 1
Brandon
  • 38,310
  • 8
  • 82
  • 87