The purpose of the article is to show what “unobtrusive JavaScript” is, what it is for, and how it is better than “intrusive” JavaScript. I have never seen such articles in runet (maybe they are, but I didn’t come across and googled a bit, I also didn’t find anything), but as practice shows, many people don’t know what it is and how to use it.
What is Unobtrusive JavaScript
')
Unobtrusive JavaScript is a JavaScript programming technique that consists of the following principles:
- separation of structure (HTML) / design (CSS) and behavior (JavaScript)
- use javascript to enhance the usability of already working application
- using Graceful degradation techniques - if the browser does not support certain functions that we add to the application using JavaScript - the application still remains working
What for?
It is convenient, it is practical, it is easy to implement and it helps you to increase the audience of your site at the expense of users using old browsers that disable JavaScript, users who use the Internet from mobile devices.
How?
The easiest way to show this is by example. You don’t need to go far behind him - let's take everyone’s beloved Habrahabr:
<div class = "text_comments">
<div class = "comment_item" style = "margin-left: 0px;">
<div class = "service_text_comments_holder">
<a href="http://fxposter.habrahabr.ru/" class="comments_nickname"> fxposter </a>
...
</ div>
<div class = "comment_text"> ... </ div>
<div class = "comments_reply">
<div class = "reply_word_holder" id = "reply_link866650"> (<a href="javascript:saw(866650);"> answer </a>) </ div>
<div style = "display: none" id = "reply866650">
<! - comment submission form ->
</ div>
</ div>
</ div>
</ div>
This is the code of comments that are displayed on the page about the post. For clarity, unnecessary fragments have been removed.
What is bad in this snippet?
- JavaScript is interspersed with HTML (
) - People with javascript disabled can’t respond to a comment in principle
How can it be improved?
- Put the "hanging" of events in a separate file
- Make it so that when JavaScript is turned off, the user is transferred to a separate page where he can respond to the selected comment.
No sooner said than done. Convert HTML to the following form:
<div class = "text_comments">
<div class = "comment_item" style = "margin-left: 0px;">
<div class = "service_text_comments_holder">
<a href="http://fxposter.habrahabr.ru/" class="comments_nickname"> fxposter </a>
...
</ div>
<div class = "comment_text"> ... </ div>
<div class = "comments_reply">
<div class = "reply_word_holder" id = "reply_link866650"> (<a href="reply.php?comment_id=866650" class="show_reply_form" id="show_reply_form_866650"> reply </a>) </ div>
<div style = "display: none" id = "reply866650">
<! - comment submission form ->
</ div>
</ div>
</ div>
</ div>
As you can see, I changed the a tag (assigned it a “normal” href, added id and class). Now, when you click on the "answer" link, the user will be transferred to the answer page for the selected question. With this, I completed the second item in the list of improvements. Now let's take a look at the first point: in order for users who have javascript enabled instead of a redirect to open a form under the comment itself, I need to select all the elements with the
show_reply_form
class and assign a function to the onclick event that would “open »Appropriate form.
Write the appropriate function:
function showForm (event) {
var id = parseInt (this.id.replace ('show_reply_form_', ''));
saw (id);
return false;
}
It takes
this.id
(i.e., the id of the current object), removes the “phrase” "
show_reply_form_
" from it, thereby obtaining the number of the element that we need to open and calls the saw function, which was originally present in the HTML code. In order to avoid a redirect after clicking on the link, the function returns
false
.
It remains only to associate this function with our links.
In
jQuery, this is done like this:
$ ('. show_reply_form'). click (showForm);
In
PrototypeJS , this is:
$$ ('. show_reply_form'). invoke ('observe', 'click', showForm);
After assigning our function to an element,
this.id
will be assigned to the id of this element (yes, this is “JavaScript magic” :)).
All JavaScript code can now be transferred to a separate file:
function showForm (event) {
var id = parseInt (this.id.replace ('show_reply_form_', ''));
saw (id);
return false;
}
document.observe ("load", function (event) {
$$ ('. show_reply_form'). invoke ('observe', 'click', showForm);
});
Here we call the "binding" of our links to the form display function at the
window.onload
event (when loading the page) using the
observe
function, which the document PrototypeJS object adds.
observe
adds to events that could already have been associated with the
window.onload
event, the event we specified. Try to use the addEventListener, observe (PrototypeJS) or $ (window) .load functions to prevent the substitution of functions already “hung” on an element.
Thus, I completed the first item in the list of improvements.
findings
In my opinion, this use of JavaScript, namely, the removal of all functions on JS into a separate file and the linking of these functions with page elements using various events (here we saw
window.onload
and
element.onclick
) - this is the only time proper use of javascript.
Dare, gentlemen. :)
Ps . I know perfectly well that you can use the event not window.onload
, but DOMContentLoaded
. But I think that, for example, it would be clearer to use window.onload
.Pps . Crosspost from here .