7

I know this question might be silly just would like to know, and I am not sure whether the topic matches to my current asking. But still thought to ask it.

  <button id="Clk">Click on me</button>

   document.getElementById("Clk").onclick = function(){alert("firedme!")}

   document.getElementById("Clk").onclick = fire();

   function fire(){alert("I am fired!")}

I see the first one "function" is not triggered on page load or refresh but where as second one fire() gets triggered
when page loaded, and later this function doesn't get triggered on click. I am confused, just need clarifications in this.

1
  • 1
    You are not executing the first one, then why are you executing the second one with those ()? Remove them and you're fine. Commented Jun 6, 2014 at 19:11

3 Answers 3

13

You need to pass fire to onclick as a function reference, not an invocation.

 document.getElementById("Clk").onclick = fire;

When you pass fire() to the onclick handler, it triggers immediately and the return from the function is what you are setting onclick too. By passing a reference to the function, it stops it from running until the event is triggered. It's essentially the same as the anonymous function handler above.

rlemon was kind enough to make you a nice demonstration fiddle <-- here

Sign up to request clarification or add additional context in comments.

Comments

7

The second one fires immediately because you used parenthesis (). When assigning an event handler to an existing function, don't include the parenthesis.

What happens is the function executes straight away, and the return value is assigned as the event handler.

To illustrate, it is the same as doing:

var result = fire();
console.log( result ); // undefined

document.getElementById("Clk").onclick = result;

As you can see, undefined is passed as the event handler.

Comments

3

Also, I would like to add few more things.

First, think of onclick as an ordinary property of an object.

So, object.onclick = value where value = functionName() is perfectly alright, for example, functionName() could be returning a value using return something;

But onclick is not an ordinary property. When JS engine in browser encounters assignments to event based properties (e.g. onclick,ondblclick,onmouseover, etc.), it creates a stack for each element, consisting of mapping b/w onSomeEvent and handler.

The handler is a function object. But if you do something like element.onSomeEvent = functionName(); you are simply calling the function functionName() and this would have been alright if functionName() was defined as

function functionName() {return function(){/*do something*/};}

But because functionName in your case is not returning a function, you see an unexpected result. This is the major drawback of languages like JavaScript. In a strongly typed language that would have thrown an error... because

class Element {
    Function onclick = null;
    Function ondblclick = null;
    /*other code*/
}
document.getElementById('idName').onclick = new Function(); // correct
document.getElementById('idName').onclick = function(){}; // correct
document.getElementById('idName').onclick = functionName();
/*
 * correct if functionName defined as 
 * Function functionName() {return new Function();} or
 * Function functionName() {return function(){};}
 * and incorrect for any other case
 */

1 Comment

It should be noted the second (or N assignments) over write previous listeners (as you described about it being a property). Using .addEventListener allows you to stack multiple listeners to an element.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.