How does inline Javascript (in HTML) work?

JavascriptHtml

Javascript Problem Overview


I know this is bad practice. Don't write code like this if at all possible.

Of course, we'll always find ourselves in situations where a clever snippet of inline Javascript can address an issue quickly.

I am pursuing this query in the interest of fully understanding what happens (and the potential pitfalls) when something like this is written:

<a href="#" onclick="alert('Hi')">Click Me</a>

As far as I can tell this is functionally the same as

<script type="text/javascript">
   $(function(){ // I use jQuery in this example
       document.getElementById('click_me').onclick = 
           function () { alert('Hi'); };
   });
</script>
<a href="#" id="click_me">Click Me</a>

Extrapolating from this it seems that the string assigned to attribute onclick is inserted within an anonymous function which is assigned to the element's click handler. Is this actually the case?

Because I'm starting to do things like this:

<a href="#" onclick="$(this).next().fadeIn(); return false;">Display my next sibling</a> <!-- Return false in handler so as not to scroll to top of page! --> 

Which works. But I don't know how much of a hack this is. It looks suspicious because there is no apparent function that is being returned from!

You might ask, why are you doing this, Steve? Inline JS is bad practice!

Well to be quite honest I'm tired of editing three different sections of code just to modify one section of a page, especially when I'm just prototyping something to see if it will work at all. It is so much easier and sometimes even makes sense for the code specifically related to this HTML element to be defined right within the element: When I decide 2 minutes later that this was a terrible, terrible idea I can nuke the entire div (or whatever) and I don't have a bunch of mysterious JS and CSS cruft hanging around in the rest of the page, slowing down rendering ever so slightly. This is similar to the concept of locality of reference but instead of cache misses we're looking at bugs and code bloat.

Javascript Solutions


Solution 1 - Javascript

You've got it nearly correct, but you haven't accounted for the this value supplied to the inline code.

<a href="#" onclick="alert(this)">Click Me</a>

is actually closer to:

<a href="#" id="click_me">Click Me</a>
<script type="text/javascript">
document.getElementById('click_me').addEventListener("click", function(event) {
    (function(event) {
        alert(this);
    }).call(document.getElementById('click_me'), event);
});
</script>

Inline event handlers set this equal to the target of the event. You can also use anonymous function in inline script

<a href="#" onclick="(function(){alert(this);})()">Click Me</a>

Solution 2 - Javascript

What the browser does when you've got

<a onclick="alert('Hi');" ... >

is to set the actual value of "onclick" to something effectively like:

new Function("event", "alert('Hi');");

That is, it creates a function that expects an "event" parameter. (Well, IE doesn't; it's more like a plain simple anonymous function.)

Solution 3 - Javascript

There seems to be a lot of bad practice being thrown around Event Handler Attributes. Bad practice is not knowing and using available features where it is most appropriate. The Event Attributes are fully W3C Documented standards and there is nothing bad practice about them. It's no different than placing inline styles, which is also W3C Documented and can be useful in times. Whether you place it wrapped in script tags or not, it's gonna be interpreted the same way.

https://www.w3.org/TR/html5/webappapis.html#event-handler-idl-attributes

Solution 4 - Javascript

The best way to answer your question is to see it in action.

<a id="test" onclick="alert('test')"> test </a> ​

In the js

var test = document.getElementById('test');
console.log( test.onclick ); 

As you see in the console, if you're using chrome it prints an anonymous function with the event object passed in, although it's a little different in IE.

function onclick(event) {
   alert('test')
}

I agree with some of your points about inline event handlers. Yes they are easy to write, but i don't agree with your point about having to change code in multiple places, if you structure your code well, you shouldn't need to do this.

Solution 5 - Javascript

>It looks suspicious because there is no apparent function that is being returned from!

It is an anonymous function that has been attached to the click event of the object.

>why are you doing this, Steve?

Why on earth are you doi.....Ah nevermind, as you've mentioned, it really is widely adopted bad practice :)

Solution 6 - Javascript

Try this in the console:

var div = document.createElement('div');

div.setAttribute('onclick', 'alert(event)');

div.onclick

In Chrome, it shows this:

function onclick(event) {
  alert(event)
}

...and the non-standard name property of div.onclick is "onclick".

So, whether or not this is anonymous depends your definition of "anonymous." Compare with something like var foo = new Function(), where foo.name is an empty string, and foo.toString() will produce something like

function anonymous() {

}

Solution 7 - Javascript

using javascript:

here input element is used

<input type="text" id="fname" onkeyup="javascript:console.log(window.event.key)">

if you want to use multiline code use curly braces after javascript:

<input type="text" id="fname" onkeyup="javascript:{ console.log(window.event.key); alert('hello'); }">

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSteven LuView Question on Stackoverflow
Solution 1 - JavascriptapsillersView Answer on Stackoverflow
Solution 2 - JavascriptPointyView Answer on Stackoverflow
Solution 3 - JavascriptDaniel BView Answer on Stackoverflow
Solution 4 - Javascriptaziz punjaniView Answer on Stackoverflow
Solution 5 - JavascriptmattytommoView Answer on Stackoverflow
Solution 6 - JavascriptDagg NabbitView Answer on Stackoverflow
Solution 7 - JavascriptTushar SahaView Answer on Stackoverflow