Unknown
Unknown

Reputation: 257

How can I move multiple DOM elements using javascript?

I have made a object called Circle and have two instances of this object called circle1 and circle2 Im trying to get them to swap positions, But only one of them is moving at the moment.

Javascript:

var gap = 6, size= 60;
var Circle = function(t,l, color){
        var elem = document.createElement('div');
        t = t,
        l = l;

        elem.setAttribute("class", "circle");
        elem.style.backgroundColor = color;

        // init positions
        elem.style.top  = gap+t*(size+2*gap) + "px";
        elem.style.left = gap+l*(size+2*gap) + "px";
        document.body.appendChild(elem);

        this.getPosition = function(){
            return [t,l];
        };

        this.setPosition = function(arr){
            t = arr[0];
            l = arr[1];
            elem.style.top  = gap+t*(size+2*gap) + "px";
            elem.style.left = gap+l*(size+2*gap) + "px";
        };
}

// make two new circle objects 
var circle1 = new Circle(0, 0, "blue");
var circle2 = new Circle(0, 1, "red");

// we need the circles to swap positions
setTimeout(function(){
    circle1.setPosition(circle2.getPosition());
    circle2.setPosition(circle1.getPosition()); // this is not working
}, 1000);

I have put this code on jsFiddle to make it easier: http://jsfiddle.net/rhL7671p/

Upvotes: 3

Views: 397

Answers (4)

Alex Char
Alex Char

Reputation: 33218

This is happening because when you try to get the position of the element has the new value. One possible solution is to use a local variable:

var gap = 6,
  size = 60;
var Circle = function(t, l, color) {
  var elem = document.createElement('div');
  t = t,
    l = l;

  elem.setAttribute("class", "circle");
  elem.style.backgroundColor = color;
  elem.style.top = gap + t * (size + 2 * gap) + "px";
  elem.style.left = gap + l * (size + 2 * gap) + "px";
  document.body.appendChild(elem);

  this.getPosition = function() {
    return [t, l];
  }

  this.setPosition = function(arr) {
    t = arr[0];
    l = arr[1];
    elem.style.top = gap + t * (size + 2 * gap) + "px";
    elem.style.left = gap + l * (size + 2 * gap) + "px";
  }


}

var circle1 = new Circle(0, 0, "blue");
var circle2 = new Circle(0, 1, "red");

// we need the circles to swap positions
setTimeout(function() {
  //use local variables to keep circles position
  var circle1Pos = circle1.getPosition();
  var circle2Pos = circle2.getPosition()
  circle1.setPosition(circle2Pos);
  circle2.setPosition(circle1Pos);
}, 200);
.circle {
  width: 60px;
  height: 60px;
  border-radius: 50px;
  background-color: red;
  position: absolute;
  -webkit-transition-property: top, left;
  -webkit-transition-duration: 0.3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 2

brbcoding
brbcoding

Reputation: 13586

Store the position of the left circle before you update the position.

setTimeout(function(){
    var c = circle1.getPosition();
    circle1.setPosition(circle2.getPosition());
    circle2.setPosition(c);
}, 1000);

var gap = 6, size= 60;
var Circle = function(t,l, color){
		var elem = document.createElement('div');
        t = t,
        l = l;
    
        elem.setAttribute("class", "circle");
        elem.style.backgroundColor = color;
        elem.style.top  = gap+t*(size+2*gap) + "px";
        elem.style.left = gap+l*(size+2*gap) + "px";
        document.body.appendChild(elem);

        this.getPosition = function(){
        	return [t,l];
        }

        this.setPosition = function(arr){
        	t = arr[0];
            l = arr[1];
        	elem.style.top  = gap+t*(size+2*gap) + "px";
        	elem.style.left = gap+l*(size+2*gap) + "px";
    	}

       	
	}

var circle1 = new Circle(0,0, "blue");
var circle2 = new Circle(0,1, "red");

// we need the circles to swap positions
setTimeout(function(){
    var c = circle1.getPosition();
    circle1.setPosition(circle2.getPosition());
    circle2.setPosition(c);
}, 1000);

console.log(circle2)
.circle{
    width:60px;
    height:60px;
    border-radius: 50px;
    background-color:red;
    position:absolute;
    -webkit-transition-property: top, left;
        -webkit-transition-duration: 0.3s;
}

Upvotes: 3

Paul S.
Paul S.

Reputation: 66304

The result of getPosition isn't what you expect after you've moved the first circle, so cache it before the move

setTimeout(function(){
    var a = circle2.getPosition(),
        b = circle1.getPosition();
    circle1.setPosition(a);
    circle2.setPosition(b);
}, 1000);

Upvotes: 2

Sirko
Sirko

Reputation: 74036

Just cache the position of the first circle:

setTimeout(function(){
   var pos = circle1.getPosition();
   circle1.setPosition( circle2.getPosition() );
   circle2.setPosition( pos );
}, 1000);

Example Fiddle

In your code after this line

circle1.setPosition(circle2.getPosition());

the position of the first circle is overwritten with the position of the second one. Hence the next line has no effect. There is no such thing as parallel execution of code in JavaScript as there is just one thread (with some exceptions ...).

To circumvent this problem: First get one (or both) position(s), and then set them afterwards.

Upvotes: 4

Related Questions