Applying position:absolute to a style via jQuery f

2019-07-21 14:25发布

This is a followup to my question here. I would like to understand why applying position:absolute to the CSS of a div via jQuery fails, while applying it in a static style works. Here are two jsfiddle examples:

Works: http://jsfiddle.net/jasper/Ty6Af/2/

No worky: http://jsfiddle.net/Ty6Af/3/

Note that the only difference between the two is where I apply position:absolute. Vertical centering always works, but horizontal centering does not work when the page loads for the first time. If you manually re-size the window the div will center correctly.

All of my testing has been on Chrome under Ubuntu thus far.

Anyway, I'm just now delving into the world of web development and these are exactly the kinds of 'quirks' that I need to begin understanding.

EDIT:

@Jasper found something interesting. If you make two calls to .css(), first applying position and subsequently applying a margin, it works. I would love to understand why. Here is an example: http://jsfiddle.net/jasper/Ty6Af/5/

4条回答
对你真心纯属浪费
2楼-- · 2019-07-21 14:55

I believe the problem is that when you apply your left and right in your second fiddle, you have yet to add position absolute to the div. Hence, the browser has no idea what do with the left and right values and ignores them initially.

Practically speaking in your second fiddle, you only actually add the position:absolute on the resize trigger. So before you resize your actual div has no positioning.

If you instead add the position absolute on load it works fine:http://jsfiddle.net/Ty6Af/9/

Notice that if you give it position:relative from the start (like this http://jsfiddle.net/Ty6Af/11/ ) it allready applies both the left and right value. The reason you can't actually see the effect of "left" is because it is a block element.

I hope that answers your question, I'm not quite clear on where you are stuck.

查看更多
三岁会撩人
3楼-- · 2019-07-21 15:09

The problem seems to be that position:absolute; negates the current layout and requires you to position it.....

See: http://jsfiddle.net/ZHaRD/

Which Jasper explains much more eloquently than myself!

查看更多
迷人小祖宗
4楼-- · 2019-07-21 15:11

http://jsfiddle.net/Ty6Af/7/ this should work, the trigger function in jquery has bugs with chrome so you have to run the function on load too.

查看更多
女痞
5楼-- · 2019-07-21 15:21

So the issue is with how the width of the div is calculated by the browser depending on its position.

  • If the div is set to position : static (by default) then it's width is 100% of it's parents width and the element is not allowed to move around the page.
  • If the div is set to position : relative then it's width is 100% of it's parents width but it can be moved around with left.
  • If the div is set to position : absolute then its width is determined by the actual content of the div, for instance if there is only a 200px wide <span> element within the div then the div will be 200px wide.

You can test these observations by changing the CSS of your jsfiddle to specify position : relative (etc...) and remove the JavaScript that makes the div position : absolute, then use your Developer Tools to inspect the element and it's calculated width.

The problem with your code is that it sets the position : absolute at the same time it sets the margin of the element by using its width/height (which are calculated differently depending on the position of the element).

If you want to set the position of the div in JavaScript then you can do something like this:

$(function() {

    //notice I cached the selector so it can be used in the future as well as set the position of the div
    $signuparea = $('#signuparea').css({position : 'absolute'});
    $(window).resize(function() {
        $signuparea.css({
            'margin-top'  : '-' + Math.round($signuparea.height() / 2) + 'px',   
            'margin-left' : '-' + Math.round($signuparea.width() / 2) + 'px',       
        });
    }).trigger('resize');
});

Here's a jsfiddle: http://jsfiddle.net/jasper/Ty6Af/8/

查看更多
登录 后发表回答