0

I am working through a tutorial here and have encountered some syntax that I don't fully understand.

I want it to be that every time I scroll, console.log logs "hello".

function moveCamera() {
  console.log("hello");
}

document.body.onscroll = moveCamera()
function moveCamera() {
  console.log("hello");
}

document.body.onscroll = moveCamera

In the first example, console.log("hello") runs once, but then never again, regardless of my scrolling.

In the second example, the code runs and logs "hello" every time there is a scroll.

I understand that for the second example, moveCamera passes a copy of the function, making a function that looks somewhat like this:

document.body.onscroll = function () {
  console.log("Hello");
}

However, I still don't understand why calling moveCamera() with parenthesis doesn't work and yields undesired functionality.

EDIT: I devised a pretty easy way to understand when to use parenthesis and when not to. I'll put it here since my question was labelled duplicate.

Without Parenthesis Examples

// Example 1: If you are assigning, use reference
document.body.onscroll = moveCamera;
// Example 2: If you are event listening, use reference
document.body.addEventListener("scroll", moveCamera);

With Parenthesis Examples

// Example 1: If you are executing on a single line alone, use call.
...
moveCamera()
...
// Example 2: If you want to repeatedly call this function, 
// like I did in my example, use a loop or an animate() function.
// @note this is a THREE.js specific example
function animate() {
  requestAnimationFrame(animate);
  moveCamera()
  renderer.render(scene,camera);
}
Gunty
  • 1,841
  • 1
  • 15
  • 27
  • 2
    `onscroll` expects a function not whatever the function returns. Functions in JS are objects that can be assigned and passed around just like arrays for example. This is called first-class functions. – elclanrs Jul 19 '21 at 00:11
  • 1
    @gunt.r to help visualise it, imagine if your first example was instead two lines: `var itsReturnValue = moveCamera();` and then `document.body.onscroll = itsReturnValue;`. As `moveCamera()` does not return anything at all, `onscroll` ends up with the value `undefined`. – Luke Briggs Jul 19 '21 at 00:39

2 Answers2

0

You should put a string with the function. Not the function itself because it would return whatever the function return. Also, I recommend to use the setAttribute() function:

document.body.setAttribute("onscroll", "moveCamera()");

  • Supposed you have this function, using moveCamera() without quotation marks:

function moveCamera() {
  return "console.log('Hello')";
}

document.body.setAttribute("onscroll", moveCamera());
body {
  height: 200vh;
}
<body></body>
  • Using moveCamera() with quotation marks as a string:

function moveCamera() {
  console.log("Hello");
}

document.body.setAttribute("onscroll", "moveCamera()");
body {
  height: 200vh;
}
<body></body>
Spectric
  • 30,714
  • 6
  • 20
  • 43
AlexSp3
  • 2,201
  • 2
  • 7
  • 24
0

If you invoke moveCamera you are assigning the value returned by the moveCamera function rather than the function itself.

This is illustrated in the following example:

function a(){
  return "b";
}
var a = a;
var b = a();

console.log("a = "+a);
console.log("b = "+b);
Spectric
  • 30,714
  • 6
  • 20
  • 43