0

In the example below, the ball is -as expected- being dropped when the mouseup event occurs:

ball.ondragstart = function() {
  return false;
};

ball.onmousedown = function(e) {
  let ballRect = ball.getBoundingClientRect();
  let shiftX = e.pageX - ballRect.left;
  let shiftY = e.pageY - ballRect.top;

  ball.style.position = "absolute";
  ball.style.zIndex = 1000;
  document.body.append(ball);

  function moveball(x, y) {
    ball.style.left = x + "px";
    ball.style.top = y + "px";
  }

  moveball(e.pageX - shiftX, e.pageY - shiftY);

  document.addEventListener('mouseup', () => {
    document.removeEventListener('mousemove', onmousemove);
    ball.onmouseup = null;
  });

  function onmousemove(e) {
    moveball(e.pageX - shiftX, e.pageY - shiftY);
  }

  document.addEventListener('mousemove', onmousemove);
}
#court {
  width: 400px;
  height: 200px;
  margin: 0 auto;
  position: relative;
  background-color: lightgreen;
  border: 1px solid green;
  border-radius: 10px;
}
#ball {
  width: 40px;
  height: 40px;
  border-radius: 100%;
  background-color: red;
  position: absolute;
}
<div id="court">
  <div id="ball">
  <div>
</div>

but when the onmousemove function definition is put inside the addEventListener function, the ball is not dropped when the mouseup event occurs (against the expectation) :

document.addEventListener('mousemove', function onmousemove(e) {
  moveball(e.pageX - shiftX, e.pageY - shiftY);
});

How does defining the named event handler inside or outside the addEventListener make a difference?

aderchox
  • 3,163
  • 2
  • 28
  • 37
  • 1
    `document.removeEventListener('mousemove', onmousemove);` does NOT remove `document.addEventListener('mousemove', function onmousemove(e) { moveball(e.pageX - shiftX, e.pageY - shiftY); });` because there is no function named `onmousemove` - since the `onmousemove` is just a name for the function expression – Jaromanda X Jun 20 '21 at 10:03
  • @JaromandaX Ah... so it's scoped differently! Thank you. – aderchox Jun 20 '21 at 10:04
  • 1
    no, not scoped differently exactly ... a named function expression isn't the same as a declared function – Jaromanda X Jun 20 '21 at 10:05
  • 1
    @JaromandaX Ok, now I think I get it, if I'm not wrong once again, it's a _named function expression_: "One key thing about a named function expression is that it creates an in-scope identifier with that name for the function within the functon body" (https://stackoverflow.com/a/15336541/9868445). Thanks again. – aderchox Jun 20 '21 at 10:22
  • 1
    sounds right, so I guess "scope" does have something to do with it :p – Jaromanda X Jun 20 '21 at 10:23

1 Answers1

1

From MDN:

The function expression's name can be used only within the function's body. Attempting to use it outside the function's body results in an error or undefined.

var y = function x() { return "Hello"; };
alert(x()); // throws an error

In contrast:

A function declaration creates a variable with the same name as the function name. Thus, unlike those defined by named function expressions, functions defined by function declarations "can be accessed by their name" in the scope they were defined in:

function x() { return "Hello"; };
alert(x()); // Hello
aderchox
  • 3,163
  • 2
  • 28
  • 37