1
votes

I have a div containing a list elements, which have static positioning and for each element I want to

  1. Record its absolute positioning using the offset() method
  2. Change its positioning to absolute, move it somewhere else, and later move it back to its original position using the recorded coordinates

First I tried this:

var positions = {};
myDiv.children().each(function(){
    var child = $(this);
    var id = child.attr('id');
    var offset = child.offset();
    positions[id] = [offset.left, offset.top];

    child .css('position', 'absolute');
    var x = ...;
    var y = ...;
    child.css('left', x);
    child.css('top', y);
});

console.log(positions);

In this case, every entry of the 'positions' object have the same coordinates (value for the first element). However, if I comment out the bit that moves the element, the positions objects has the correct coordinates for each child.

So I'm guessing it's a synchronisation issue, because the css function is called before the offset function has terminated.

So what I need really, is to make sure that the block child.css('left', x); child.css('top', y); is only executed when the 'offset' function is done.

I tried things like

$.queue(child, 'foo', function() {
        var offset = $(this).offset();
        positions[id] = [offset.left, offset.top];
        jQuery.dequeue(this);
    });
$.dequeue(child, 'foo');
child.promise().done(function() {
        child.css('position', 'absolute');
        ...
    });

but with no luck: when I log the positions objects it still has the wrong coordinates.

I am quite new to JS and JQuery so I'm sure how to do the right thing here.

How can I make sure the block child.css('left', x); child.css('top', y); will only be executed after the 'positions' object has been populated with the correct offset coordinates?

EDIT I just realised that in my case I need to use 'position()' rather than 'offset()' but that doesn't really change the problem that I have described

1

1 Answers

3
votes

In .each() changing sibling elements' position could be cause of getting wrong coordinates after the first one.

Why don't you get and store all positions before changing? I mean you should iterate childrens double times.

  1. Iterate childrens and store position, don't change any css,
  2. Iterate childrens again and change css.