whatscool
whatscool

Reputation: 317

Why is my function running on all created elements?

I have written a basic function (celebrate) that runs onmouseenter a link on my page.

It creates a p element and then calls a function (move) which moves the element from the right to the left of the page.

I want this move function to run even if you mouseleave the element.

Unfortunately, not only does the moving text dissappear when you mouseout, but all the links move at the same rate. If an element starts moving and you mouseover to create a new moving element, it moves both the moving elements back to the right hand side and moves them in line with each other.

I know I'm doing something wrong with the code but I don't know what :)

function celebrate(link) {
    let celebration = document.createElement("p");
    let celebrationtext = document.createTextNode(link.text);
    celebration.appendChild(celebrationtext);
    document.body.appendChild(celebration);
    celebration.className = 'moving';
    celebration.style.top = link.getBoundingClientRect().top;
    move(celebration, 1100);
}

function move(object, X){
    let thisobject = object;
    console.log(thisobject);
    if ( object != null ) {
        intX=X-3;
        thisobject.style.left = (intX).toString() + 'px';
    } //if
    if ( X > 0 ) { 
        setTimeout(function(){move(thisobject,intX)},20); 
    } else {
        thisobject.remove();
    }
    return true;
}

I have created a JSfiddle using the chapter titles of Eloquent Javascript

jsFiddle

Upvotes: 2

Views: 64

Answers (2)

Karan
Karan

Reputation: 12629

Update your setTimeout function as below.

setTimeout(move, 20, thisobject, intX);

Above is the proper way to pass parameters with setTimeout.

It is like setTimeout(function, timeout, param1, param2,..)

Updated fiddle: https://jsfiddle.net/evg7npbL/

Upvotes: 1

Gabriele Petrioli
Gabriele Petrioli

Reputation: 196162

That is because your intX is a global and all move(thisobject,intX) use it.

If you declare inside the move function it gets fixed.

let thisobject = object,
    intX;

updated fiddle: https://jsfiddle.net/63njmxrt/6/


Or you could remove the intX completely and just decrease the X when passing it as a parameter

function move(object, X) {
  let thisobject = object;

  if (object != null) {
    thisobject.style.left = (X).toString() + 'px';
  } //if
  if (X > 0) {
    setTimeout(function() {
      move(thisobject, X-3)
    }, 20);
  } else {
    thisobject.remove();
  }
  return true;
}

Upvotes: 2

Related Questions