0

I have the following html

<div id="to-sort">
    <div class="block" data-id="1">aaaaa</div>
    <div class="block" data-id="2">bbbbb</div>
    <div class="block" data-id="3">ccccc</div>
    <div class="block" data-id="4">ddddd</div>
    <div class="block" data-id="5">eeeee</div>
    <div class="block" data-id="6">fffff</div>
    <div class="block" data-id="7">ggggg</div>
    <div class="block" data-id="8">hhhhh</div>
    <div class="block" data-id="9">iiiii</div>
</div>

I want to iterate through each .block and set its position to be absolute. I have the following

// Iterate through .blocks
$('.block').each(function(i,v){
    var cssobj = { position: 'absolute', 
                   top: $(this).position().top, 
                   left: $(this).position().left };

    console.log(cssobj);
    //$(this).css(cssobj);
});

If the line

//$(this).css(cssobj); 

is commented out - console.log() shows the correct positions. If I uncomment

$(this).css(cssobj); 

then they are all set to the position of the first .block (x:0, y:0)

I am sure this to do with scope but I tried a closure and couldnt get it to work. How do i set each div to be an absolute position?

Thanks

32423hjh32423
  • 3,048
  • 7
  • 44
  • 59
  • what are your reference points for absolute position ?? what offset values you are getting? – kobe Jul 05 '11 at 01:33

2 Answers2

1

jQuery .position() gets the offset relative to the offset parent: http://api.jquery.com/position/

jQuery .offset() is what you are looking for.

Also after the first one sets itself to absolute the next one moves up in its place.

instead put it in two passes:

$('.block').each(function(){
    var cssobj = {top: $(this).offset().top, left: $(this).offset().left };
    $(this).css(cssobj);
}).each(function(){ $(this).css('position', 'absolute')});

EDIT:-

as an alternative you can do it in reverse order and that will work also:

$.fn.reverse = [].reverse;
$('.block').reverse().each(function(i,v){
    var cssobj = {position: 'absolute',
                  top: $(this).offset().top, 
                   left: $(this).offset().left };

    console.log(cssobj);
    $(this).css(cssobj);
});

.reverse() is from JQuery .each() backwards

Community
  • 1
  • 1
James Khoury
  • 21,330
  • 4
  • 34
  • 65
  • Thanks but this doesnt work - .position() is giving the correct coordinates in the console, but when I try and apply them - it applies the same x and y to all of them (one value for x and one for y) – 32423hjh32423 Jul 05 '11 at 01:34
  • Thats because when the first is set to absolute the next one moves up underneath it and gets the same value. try one of my edited scripts. (check it out at jsfiddle: http://jsfiddle.net/3Qmnq/) – James Khoury Jul 05 '11 at 01:39
  • 1
    @nelic, James' code does work. If you prefer using position(), that's fine, but the important point here is the "ORDER" of applying CSS, first apply "top" & "left" property, and THEN apply "position:absolute" – Neverever Jul 05 '11 at 01:39
  • 1
    @Neverever - I made that comment based on the first answer which was subsequently changed. Hard to keep up with a changing answer :) – 32423hjh32423 Jul 05 '11 at 01:43
  • @neilc My bad. I posted too early before I had the lightbulb moment. – James Khoury Jul 05 '11 at 01:44
-1

The following code looks wrong to me

when you want to to position absolute , you should get left and top vales and set them position:absolute and give top and left.

Here you are getting the same object's position top and left, how are those objects intially positioned? are the in the document flow or not, get the rerference element offset values and calculate your top and left values.

$('.block').each(function(i,v){
    var cssobj = { position: 'absolute', 
                   top: $(this).position().top, 
                   left: $(this).position().left };

    console.log(cssobj);
    //$(this).css(cssobj);
});
kobe
  • 15,671
  • 15
  • 64
  • 91