Javascript replacements for on(event) attributes - javascript

If this sounds like I'm asking for opinion, sorry I'm not expressing myself better.
My question is, why is it necessary to replace attributes like onclick by anonymous functions? What is the advantage?
For example, I have a web page that needs to be brought up to date, so I need to replace
<input id="text" onfocus="this.blur()">
by
<input id="text">
.
.
<script>
$('#text').focus(function(){this.blur()});
<script>
But what does this do? What is the specific advantage of this over the original? I searched, but I couldn't find any real reason, only opinions.

There are many reasons not to use dom0 events.
You can find some of these under the topic "unobtrusive javascript".
http://en.wikipedia.org/wiki/Unobtrusive_JavaScript
Decoupling the markup and the behaviour is the most obvious one

The main advantages are clarity and flexibility:
Limiting ad-hoc javascript code is considered as a good practice since all your javascript logic will be found in one place.
It allow you to write decoupled code and "non-obstrusive" javascript, which basically means that you will be able to easily change the behavior of your webpage without touching the HTML.
You can say than using "onenvent" attributes over event handlers is quite the same as using the style attribute over an attached CSS file.
using the on() function allows to add as many event listeners as you see fit.

One good advantage is that this keeps your HTML simpler & lighter and could be loaded and rendered faster while your javascript on the bottom is still being loaded. If you consider performance its better to load HTML (& css) at the very beginning and scripts at the last.
Also, it separates code from the markup, making everything less
messed up, more systematic and easier to debug.
And you can't simply write bulky java script code in attributes it becomes inconvenient, you'd have to write in functions anyway for complex logic.

No one has mentioned that inline handlers are a vector for XSS attacks.
Keeping JavaScript out of HTML allows you to harden your site and set a Content-Security-Policy: script-src 'self'
that disable JavaScript in HTML.

Related

JavaScript doesn't have to be inside a <script> tag?

The following code seems to execute JavaScript when the page finishes loading.
<html>
<head>
<title>test page</title>
</head>
<body onload="alert('The page has finished loading');">
</div>
</body>
</html>
I thought that all JavaScript code has to be encapsulated in between <script> and </script>. So why was that not the case here?
This is an inline event handler, which contains Javascript code.
They're generally frowned upon.
Note that Javascript can also appear in javascript: URIs (such as bookmarklets).
JavaScript can be included in a page via:
A script element referencing an external file
Inline in a script element
An intrinsic event attribute (as in your example)
Anywhere that accepts a URI and doesn't block JS URIs for security reasons (once upon a time <img src="javascript:someScriptHere()"> worked, <a href="javascript:someScriptHere()"> still does)
Various proprietary extensions to CSS (such as expression)
Generally speaking, only the first of those techniques is a recommended method. Avoid the others.
Not all JavaScript needs to be encapsulated so. This is part of the reason simply stripping out tags to remove XSS is not enough.
W3C spec
Avoiding XSS
This called "inline JavaScript"! Like inline CSS, inline JavaScript also is not a good practice.
One of the reasons why we shouldn't use inline event handlers is that it requires us to mix JavaScript code in with our HTML/XHTML code.
Other reasons are that it means cluttering up the HTML code with vast numbers of event handlers, whereas with scripting we can apply event handlers to any parts of the page, and even use a single event handler to handle events across multiple elements.
HTML for the content, CSS for the presentation, and JavaScript for the behavior. By keeping a separation of behavior between these parts, we increase their ability to be maintained, and used across a wide range of situations.
This is not to say that inline event handlers are always a bad thing to do. Instead, realise that the use of them becomes a restriction on being able to more flexibly manage and maintain them. Take a look at following articles for more information regarding this concerns:
http://css.dzone.com/news/why-inline-css-and-javascript-
http://www.digital-web.com/articles/separating_behavior_and_structure_2/

Why not use inline CSS if all the HTML+CSS is generated at runtime by javascript and no developer will need to work with css and html?

The only reasons I see on the internet to not to use inline-css is because of the separation of html and css & management, but if this is not a problem in my case I don't care I will use.
Another pro I can say is this: imagine you want to load a widget made by another user, you will only need to load 1 file, the javascript and not the css.
But it might have other problems?
thanks
If you read your question again, you have answered it yourself. There is a reason for the "separation" of html and CSS. Because at some point in time, you will eventually want to change the look of what you have coded up. These are the times when having a separate CSS file would be very helpful so you are only ever making changes in one place and not throughout your application.
EDIT
Another usefulness of having the CSS separate is the caching. Most of the modern browsers cache the CSS files. This means there are less round-trips to the server and quicker response times. I'm not sure if same is the case for JavaScript, because JavaScript files would be cached, but the client browser will have to execute the code every time it loads.
I think this is a good question that is worth exploring. I don't think there is a performance or standards-based argument for not using inline CSS - it works perfectly well - the only (though considerable) argument for separated CSS is for maintainability / readability. And so if you are generating CSS from JavaScript, generating it inline is just as sound as any other way.
In fact, DOM APIs in general expose much simpler methods for assigning styles directly to elements ( https://developer.mozilla.org/en/DOM/element.style ) than for creating new stylesheets. Therefore almost all JavaScript libraries, like jQuery, when they have to manipulate styles they do it by adding inline styles to an element.
Having said that, I have never before seen a situation where the mark-up and styling for a whole page was generated with JavaScript. I would expect this to be rather inefficient. I can see that if you have a web application where all content is pulled in through Ajax (a perfectly good solution) then you might write a fair bit of the mark-up with JavaScript, but still it would be better/more efficient to load most of the surrounding mark-up for your content in the initial page load, and then use JavaScript to swap out content within existing elements.
In any case, I would recommend that you keep most of your CSS in an external stylesheet with relevant classes already defined, so that all your JavaScript does is create elements with the correct class. This would have a performance advantage and would also mean that all your style information was located in one place, and is separate from your JavaScript, which would make your code easier to maintain.
It's OK to use inline css. (in this specifice case)

Why are more people nowadays using script to assign events handlers vs assigning the event from within the html element?

As a learner I like to look at lots of source code. Since I started learning JavaScript about a year ago, I notice a trend of people not using traditional event handlers as in onclick="doSomething()", but are more and more using methods like document.getElementById("someId").onclick = function(){..some code..};
What's the reason behind this trend?
Assigning the handlers in Javascript puts all of the code in one place instead of scattering it throughout the HTML.
This helps separate content from script, just like CSS helps separate content from style.
It's also faster, since the browser won't need to fire up a Javascript parser for each handler attribute.
This is an example of Unobtrusive Javascript.
The other answers haven't touched on this, so:
Your example uses the (reflected) onclick attribute even in the JavaScript code:
document.getElemenbyId("someId").onclick = function(){..some code..};
...which for me misses out one of the primary reasons for doing this without using attributes: Playing nicely with others. The DOM2 way of attaching handlers (addEventListener, or attachEvent on IE [IE9 has the standard addEventListener finally]):
document.getElementById("someId").addEventListener("click", function() { ... }, false);
// or
document.getElementById("someId").attachEvent("onclick", function() { ... });
... is non-exclusive — more than one handler can be attached at the same time. Whereas if you assign to onclick, you're kicking any previous handler off and taking over.
To me, this "playing nicely" thing is a big sell. Well, that and keeping code and markup separate, but that's been well-covered in other answers.
HTML should be only markup, pure content.
Design should be in CSS style sheet.
Dynamic scripting should be in JavaScript code, separate file is good.
Just feels better and looks better - as far as I can tell it's not more efficient just more elegant and easier to maintain when all the script is in one place instead of being spread all across the HTML. :)
As mentioned by other answers, the main reason is separation of concerns (in this case, keeping behaviour separate from content), which is entirely sensible. However, that isn't always the only consideration. I've previously written a lengthy answer to a related question.
I think most people are using jQuery. $("#someId").click(function(){}) and when you want to attach an event to many elements jQuery makes it easy and puts your function in one place.

onClick w/ DOM vs. onClick hardcoded

In javascript, what are the pro's and con's of encoding an onclick event in the DOM and in the HTML itself?
Which, if either, is better than the other and why?
Your question almost answers itself when you refer to "the HTML itself".
JavaScript is not HTML -- Keeping the HTML and the JavaScript in separate locations is a benefit all by itself. Makes it easier to (humanly) read the HTML, and keeping all the JS in the same location makes it easier to track everything down all at once.
It is better to write your Javascript in Javascript, as OtherMichael says. It is even better to use proper DOM events (addEventListener and attachEvent) rather than on_____, in order to avoid conflicts and allow multiple callbacks for the same event.
Attaching events to an CSS-style ID (or classes), as Jquery does so well, means that if you don't have JS enabled, it will automatically fall through to any links that are referenced. That's good practice, and will help to make sure that your page works in even quite simple browsers, such as some mobile handsets.
It's also good practice to layer the underlying data (the HTML), presentation (CSS) and behaviour (Javascript). Changing individual layers is a lot easier if they are well structured.

Why Stackoverflow binds user actions dynamically with javascript?

Checking the HTML source of a question I see for instance:
<a id="comments-link-xxxxx" class="comments-link">add comment</a><noscript> JavaScript is needed to access comments.</noscript>
And then in the javascript source:
// Setup our click events..
$().ready(function() {
$("a[id^='comments-link-']").click(function() { comments.show($(this).attr("id").substr("comments-link-".length)); });
});
It seems that all the user click events are binded this way.
The downsides of this approach are obvious for people browsing the site with no javascript but, what are the advantages of adding events dynamically whith javascript over declaring them directly?
You don't have to type the same string over and over again in the HTML (which if nothing else would increase the number of typos to debug)
You can hand over the HTML/CSS to a designer who need not have any javascript skills
You have programmatic control over what callbacks are called and when
It's more elegant because it fits the conceptual separation between layout and behaviour
It's easier to modify and refactor
On the last point, imagine if you wanted to add a "show comments" icon somewhere else in the template. It'd be very easy to bind the same callback to the icon.
Attaching events via the events API instead of in the mark-up is the core of unobtrusive javascript. You are welcome to read this wikipedia article for a complete overview of why unobtrusive javascripting is important.
The same way that you separate styles from mark-up you want to separate scripts from mark-up, including events.
I see this as one of the fundamental principals of good software development:
The separation of presentation and logic.
HTML/CSS is a presentation language essentially. Javascript is for creating logic. It is a good practice to separate any logic from your presentation if possible.
This way you can have a light-weight page where you can handle all your actions via javascript. Instead of having to use loads of different urls and actions embedded into the page, just write one javascript function that finds the link, and hooks it up, no matter where on the page you dump that 'comment' link.
This saves loads of repeating html :)
The only advantage I see is a reduction of the page size, and thus a lower bandwith need.
Edit: As I'm being downvoted, let met explain a more my answer.
My point is that, using a link as an empty anchor is just a bad practice, nothing else! Of course separation of JavaScript logic from HTML is great. Of course it's easier to refactor and debug. But here, it's against the main principle of unobtrusive JavaScript: Gracefull degradation!
A good solution would be to have to possible call of the comments: one through a REAL link that will point to a simple page showing the comment and another which returns only the comments (in a JSON notation or similar format) with the purpose of being called through AJAX to be injected directly in the main page.
Doing so, the method using the AJAX method should also take care of cancelling the other call, to avoid that the user is redirected to the simple page. That would be Unobtrusive JavaScript. Here it's just JavaScript put on a misused anchor tag.

Categories

Resources