-1

Why is it that when you do this:

var foo = document.getElementById("foo");
foo.addEventListener("keydown", foo);
function foo(e){
 console.log(e.keyCode);
}

Why do you not need this:

var foo = document.getElementById("foo");
foo.addEventListener("keydown", foo(e));
function foo(e){
 console.log(e.keyCode);
}

But in some cases if you are passing something through parameter you would do this:

var foo = document.getElementById("foo");
foo.addEventListener("keydown", foo("Hello, world!"));
function foo(e){
 console.log(e);
}

WHY WHY WHY!!!

GtiClicker
  • 78
  • 8
  • 1
    You need to use a different variable name for the function and for the DOM element. There is a huge difference between a function (object) and the return value you get from calling a function. Quite unrelated. Your question is littered by mistakes in the code blocks you provided. – trincot Mar 09 '21 at 22:24
  • THIS IS NOT A CALL TO A FUNCTION, this is an argument with the reference to a **listener function** – Mister Jojo Mar 09 '21 at 22:25

1 Answers1

2

But in some cases if you are passing something through parameter you would do this:

var foo = document.getElementById("foo");
foo.addEventListener("keydown", foo("Hello, world!"));

function foo(e){
 console.log(e);
}

No, you wouldn't. That would invoke foo with it's argument immediately and whatever the return value from calling it was (in your example, undefined), is what would then become the callback reference for the keydown event and undefined can't be a callback reference.

Let's see that in action. Below, "Hello, world!" is written to the console immediately and nothing happens when you key down in the input:

var input = document.getElementById("input");
input.addEventListener("keydown", foo("Hello, world!"));
function foo(e){
 console.log(e);  // Immediately written to console!
}
<input id="input">  

The second parameter for .addEventListener() takes a function reference, which you can provide in several ways:

Supply the name (no parenthesis) of the function:

 .addEventListener("click", foo);

Supply an anonymous function (which doesn't invoke the function, just passes it):

 .addEventListener("click", function(){ // function body  });

Supply code to execute that returns a function (note the parenthesis here) which will invoke foo first and the return value from foo, which should be a function, will be the callback reference:

 function foo(){
   return function(){ console.log("Hello, world!");  };
 }

 .addEventListener("click", foo());  // foo is invoked first

But, as you can see, if you include the parenthesis, you are invoking the function right away, so if foo needs to be the function reference AND it takes arguments, you can't write this if foo doesn't return a function: .addEventListener("click", foo(arg));

So, instead you have to wrap the function call in an anonymous function that we saw earlier:

function foo(e){
 console.log(e);  
}
var input = document.getElementById("input");

// The anonymous function is the reference to execute when 
// the event is triggered. When that happens, the anonymous
// function will call foo with its arguments.
input.addEventListener("keydown", function(){ foo("Hello, world!"); });
<input id="input">
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71