Home > Software design >  Why my div shake after Javascript events are executed?
Why my div shake after Javascript events are executed?

Time:08-13

This is supposed to happen:

I mouseover my box, the box moves 50px to the right, and when I mouseleave the box, the box returns to its original position.

This happens:

The box moves to the right when mouseover, and moves to its original position when I mouseleave. But if I do this a few times, the box starts shaking. The more times I do it, the more it shakes.

How do I keep it from shaking after I mouseover/mouseleave several times? I assume I need some sort of removeEventListener inside the functions, and addEventListeners, but I am farely new to this stuff.

const box1 = document.getElementById("divContainer");
let box1Left = parseInt(box1.style.marginLeft = 0   "px");

function moveBox1Right() {
  let id = null;
  clearInterval(id);
  id = setInterval(x, 5);

  function x() {
    if (box1Left == 50) {
      clearInterval(id);
    } else {
      box1Left  ;
      box1.style.marginLeft = box1Left   "px";
    }
  }
}

box1.addEventListener("mouseover", moveBox1Right)

function moveBox1Left() {
  let id = null;
  clearInterval(id);
  id = setInterval(y, 5);

  function y() {
    if (box1Left >= 1) {
      box1Left--;
      box1.style.marginLeft = box1Left   "px";
    } else {
      clearInterval(id);
    }
  }
}

box1.addEventListener("mouseleave", moveBox1Left);
#divContainer {
  height: 100px;
  width: 100px;
  background-color: #c5c5c5;
}
<div id="divContainer">
</div>

CodePudding user response:

If you mouse in/out during the "animation" both intervals can theoretically be active at the same time, causing the shake. The intervals are only cancelled when it reaches it's end condition, not when another interval is started, the mouse enters/leaves, or the direction is presumably intended to change.

You may want to share id between the two functions as your clearInterval(id) at the start of each function does nothing (id = null in the line before always means you're clearing null).

Better, you may want to consider using CSS animate which can solve this issue fairly elegantly.

CodePudding user response:

Move the timeout reference (let id) outside the functions. It is pointless to clear the id if you set it to null and you need to share it and use the reference when you clear it

let id;

function moveBox1Right() {
  clearInterval(id);
...
function moveBox1Left() {
  clearInterval(id);
  • Related