Tuesday, October 25, 2016

Why can't we use click() as button's event handler function name in JavaScript?

As JavaScript developers, many of us might have encountered situation where we defined a function for handling events such as Button's onclick and the function never gets executed. After long time of googling, when we change the name of function, it just starts working and we move to next step without digging why it didn't work for that function name. This post is a small journey towards the answer of why we can't have click() to handle button.onclick.

Lets start with code to see what is this issue. Below code is a simple HTML file which has 2 buttons with ids btn1 and btn2 respectively. Both the buttons have onclick event handled.

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <script type="text/javascript">
        function click() {
            alert("click");
        }

        function click_handler() {
            alert(this);
            alert("click_handler");
        }
    </script>
</head>
<body>
    <button id="btn1" onclick="click()">btn1 uses click()</button>
    <button id="btn2" onclick="click_handler()">btn2 uses click_handler()</button>
</body>
</html>

For btn1 click function is used as onclick hander and for btn2 the handler function is click_handler. If we save these contents as html file and run, we could see that the btn2 click is handled properly by calling the click_handler(). But btn1's click() is never invoked. What is happening here?

Quick google may tell us that there is already a click() method defined globally or at document level to call the event handlers and that is the reason why our click() is not working.

But if we use F12 developer tools and check click function on window and document we could see its undefined.

Note:We have to check for system defined click function by removing our click function. Else it will see our click function.

Before going to next steps lets see what will happen if we introduce below line to the above HTML page just above closing of body tag ie above </body>

    <button id="btn3" onclick="window.click()">btn3 uses click()</button>

We can see the btn3 click is invoking the event handler function click(). So there is nothing special about the function name click(). Hence we can conclude that the issue of conflicting names is somewhere else.

Is there any click function on the button element? 

Now lets check if there is any click function defined already in the button element? For that put a break point anywhere in the click_handler() and run with F12 developer tools open.

Click on the btn2 and type the below line in the F12 console window.

   document.getElementById('btn1').click 

We can see the below output which confirms there is a system defined click function on the button object.

function click() { [native code] }

This confirms the reason for name conflict. Below code lists all the functions defined on button element.

for(var p in document.getElementById('btn1'))
    if(typeof document.getElementById('btn1')[p] === "function") 
      console.log(p);

Happy Scripting...

No comments: