I am curious about how the content of the inline element attribute event works under the hood.
We start off with a simple function
function handler(e) {
console.log(e);
}
Use Case 1
If we would want to add this handler to our button we could do:
<button onclick="handler();">Click Me</button>
Which Logs on click: undefined
Fair enough, we called a function without passing arguments.
Use Case 2
If we now change the button to take the event
as an argument:
<button onclick="handler(event);">Click Me</button>
We log on click: MouseEvent{ ... }
Now we log the event, as we could have expected
Use Case 3
But what if we just specify the function name?
<button onclick="handler">Click Me</button>
Nothing happens!, I was hoping just giving a reference to a function, would do the trick. So when "onlick" would happen, the referred function would be called with the proper event argument.
Use Case 4
When we add the handler in javascript:
const btn = document.getElementById('btn');
btn.onclick = handler;
it works, capturing the event and logs the related event
object.
Concluding Question
Whatever text/content/statement that we pass to onclick=""
inline, does it basically run eval()
on it? And when we attach it in javascript (btn.onclick = ...
) it goes through the proper process to intercept the event and then call bounded handler function and passes the corresponding event object with it (e.g. MouseEvent
)?
Quick Note
To be clear, this is an informative question, to understand the fundamentals, disregarding if it's considered a bad or good practice. That's not being discussed at this point.
The onclick event attribute in HTML works when the user clicks on the button. When the mouse clicked on the element then the script runs. Attribute Value: This attribute contains a single value script that works when the mouse clicked on the element.
Note that the onclick attribute is purely JavaScript. The value it takes, which is the function you want to execute, says it all, as it is invoked right within the opening tag. In JavaScript, you invoke a function by calling its name, then you put a parenthesis after the function identifier (the name).
For little web apps with a minimal amount of code, it doesn't matter. But if you aspire to write large, maintainable codebases, onclick="" is a habit that you should work to avoid.
If you called onclick ( element. onclick() ), you'd call the function attached to it — but not handlers attached with modern methods. E.g., click triggers a fake click; the other lets you set up a handler for clicks. (If you call onclick , it'll only call the handler attached via that old DOM0 mechanism.)
You may inline any javascript inside the onclick as if you were assigning the method through javascript. This isn't really recommended, but you can do it all inline like so: But I can't think of any situations off hand where this would be better than writing the function somewhere else and invoking it onClick.
The onclick event generally occurs when the user clicks on an element. It allows the programmer to execute a JavaScript's function when an element gets clicked. This event can be used for validating a form, warning messages and many more. Using JavaScript, this event can be dynamically added to any element. It supports all HTML elements ...
Here we are using the onclick event with the paragraph element. When the user clicks on the paragraph element, the corresponding function will get executed, and the text of the paragraph gets changed. On clicking the <p> element, the background color, size, border, and color of the text will also get change.
The ng-click directive functions are based on the event click, which means as soon as HTML view experiences a click (a mouse click) on a particular HTML element, then its corresponding ng-click expression is evaluated.
Yes, in an inline handler, the attribute text is essentially just eval
ed, with a few qualifications. What
<button onclick="handler">Click Me</button>
is roughly equivalent to would be if you had a (true) handler which referenced the handler
function but didn't call it, for example:
btn.onclick = () => {
handler;
};
This doesn't throw an error (because handler
is referenceable), but it doesn't run handler
either, because you're only referencing the function, not calling it.
When you do
btn.onclick = handler;
you are passing a reference to handler
to the onclick
internals, which then call that reference later, when the button is clicked.
(If you had done btn.onclick = handler;
, handler
would be invoked immediately, and its return value would be added as a listener, which isn't what you'd want)
When you do
<button onclick="handler(event);">Click Me</button>
the event
argument you're passing comes from window.event
, which is why it's referenceable.
Like I said, there are a few qualifications, though: inline handlers implicitly use something like a with(this)
around the whole text that is run, where this
is the element in question. (it also uses with
for the document
and containing form, as you can see from Quentin's answer) For example:
<a onclick="search();">Click me!</div>
looks, to the interpreter, a bit like:
<a onclick="
with(this) {
search();
}
">Click me!</div>
which is problematic, because search
is a property of HTMLAnchorElement.prototype
. Referencing other variable names can have similar problems, if those variable names are properties anywhere on the element's prototype chain.
Best to avoid inline handlers entirely, and attach the event properly using Javascript instead.
This is not what happens, but you can imagine it like this:
Imagine that the javascript engines saves the content of the onclick
attribute as a string, and when a user clicks the element, then evaluates the content.
For example:
function foo(a, b) {
alert(a + ' ' + b);
}
<button onclick="foo('hello', 'world')">click me</button>
<button onclick="(function () { alert ('I\'m an inline IIFE') })()">click me</button>
It's the same result of eval("foo('hello', 'world')"
. What if you pass event
or this
or other keywords?
Well, also here, you can imagine a javascript engines doing this:
var this = /* create context */;
var event = /* create event */;
eval("foo(this, event)");
This is what the specification says, the attribute needs to be evaluated! I'm not saying that the engine uses eval
:P
Example:
<button onclick="alert('hello world')">Click me</button>
What about btn.onclick = handler;
?
This is another pair of shoes. The onclick
property is a callback, and it wants a function reference.
When you use HTML attribute for the event, you actually create a function under the hood which assigned as the handler of the relevant event.
event
parameterSo,
In case 1, The generated handler :
function handlerHtml(event) {
handler()
}
In case 2, The generated handler :
function handlerHtml(event) {
handler(event)
}
In case 3, The generated handler :
function handlerHtml(event) {
handler
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With