Цель статьи — показать, что из себя представляет «ненавязчивый JavaScript», для чего он нужен, и чем он лучше «навязчивого» JavaScript. В рунете я подобных статей не встречал (может они и есть, но мне на глаза не попадались и немного погуглив, я тоже ничего не нашел), а как показывает практика — очень многие не знают, что это такое и как этим пользоваться.
Unobtrusive JavaScript — это техника программирования на языке JavaScript, которая состоит из следующих принципов:
Это удобно, это практично, это легко реализуемо и это помогает Вам увеличить аудиторию вашего сайта за счет пользователей, пользующихся старыми браузерами, отключающими JavaScript, пользователей, которые пользуются интернетом с мобильных устройств.
Легче всего показать это на примере. За ним далеко идти не нужно — возьмем всеми любимый Хабрахабр:
Это код комментариев, которые показываются на страничке о посте. Для наглядности ненужные фрагменты были убраны.
Что плохо в этом фрагменте кода?
Как его можно улучшить?
Сказано — сделано. Преобразуем HTML к следующему виду:
Как видите — я изменил тег a (присвоил ему «нормальный» href, добавил id и class). Теперь при нажатии на ссылку «ответить» пользователя будет перебрасывать на страницу ответа на выбранный вопрос. Этим я выполнил второй пункт в списке улучшений. Теперь давайте взглянем на первый пункт: для того, чтобы у пользователей, у которых включен JavaScript вместо редиректа выполнялось открытие формы под самим комментарием мне нужно выбрать все элементы с классом "
Напишем соответствующую функцию:
Она берет
Осталось только связать эту функцию с нашими ссылками.
В jQuery это делается так:
В PrototypeJS — так:
После присвоения нашей функции элементу —
Весь JavaScript-код теперь можно вынести в отдельный файл:
Здесь мы вызываем «связывание» наших ссылок с функцией показа формы при событии
Таким образом я выполнил и первый пункт в списке улучшений.
На мой взгляд, такое использование JavaScript, а именно — вынос всех функций на JS в отдельный файл и связывание этих функций с элементами страницы с помощью различных событий (здесь мы видели события
Дерзайте, господа. :)
PS. Я прекрасно знаю, что можно использовать событие не
PPS. Кросспост отсюда.
Что такое Unobtrusive JavaScript
Unobtrusive JavaScript — это техника программирования на языке JavaScript, которая состоит из следующих принципов:
- разделения структуры (HTML) / оформления (CSS) и поведения (JavaScript)
- использование JavaScript для повышения удобства использования уже рабочего приложения
- применения техники Graceful degradation — если браузер не поддерживает те или иные функции, которые мы добавляем в приложение с помощью JavaScript — приложение всё равно остается рабочим
Зачем?
Это удобно, это практично, это легко реализуемо и это помогает Вам увеличить аудиторию вашего сайта за счет пользователей, пользующихся старыми браузерами, отключающими JavaScript, пользователей, которые пользуются интернетом с мобильных устройств.
Как?
Легче всего показать это на примере. За ним далеко идти не нужно — возьмем всеми любимый Хабрахабр:
<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);">ответить</a>)</div> <div style="display: none" id="reply866650"> <!-- форма отправки комментария --> </div> </div> </div> </div>
Это код комментариев, которые показываются на страничке о посте. Для наглядности ненужные фрагменты были убраны.
Что плохо в этом фрагменте кода?
- JavaScript идет вперемешку с HTML (
ответить
) - У людей с отключенным JavaScript'ом ответить на комментарий не получится в принципе
Как его можно улучшить?
- Вынести «навешивание» событий в отдельный файл
- Сделать так, чтобы при отключенном JavaScript'е пользователь перебрасывался на отдельную страницу, где бы он мог ответить на выбранный комментарий
Сказано — сделано. Преобразуем HTML к следующему виду:
<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">ответить</a>)</div> <div style="display: none" id="reply866650"> <!-- форма отправки комментария --> </div> </div> </div> </div>
Как видите — я изменил тег a (присвоил ему «нормальный» href, добавил id и class). Теперь при нажатии на ссылку «ответить» пользователя будет перебрасывать на страницу ответа на выбранный вопрос. Этим я выполнил второй пункт в списке улучшений. Теперь давайте взглянем на первый пункт: для того, чтобы у пользователей, у которых включен JavaScript вместо редиректа выполнялось открытие формы под самим комментарием мне нужно выбрать все элементы с классом "
show_reply_form
" и каждому из них назначить на событие onclick функцию, которая бы «открывала» соответствующую форму.Напишем соответствующую функцию:
function showForm(event) { var id = parseInt(this.id.replace('show_reply_form_', '')); saw(id); return false; }
Она берет
this.id
(т.е. id текущего обьекта), убирает из него «фразу» "show_reply_form_
", тем самым получая номер элемента, который нам нужно открыть и вызывает функцию saw, которая присутствовала изначально в HTML-коде. Для того, чтобы не произошел редирект после клика на ссылку — функция возвращает false
.Осталось только связать эту функцию с нашими ссылками.
В jQuery это делается так:
$('.show_reply_form').click(showForm);
В PrototypeJS — так:
$$('.show_reply_form').invoke('observe', 'click', showForm);
После присвоения нашей функции элементу —
this.id
станет относится к id этого элемента (да, это «магия JavaScript» :) ).Весь JavaScript-код теперь можно вынести в отдельный файл:
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); });
Здесь мы вызываем «связывание» наших ссылок с функцией показа формы при событии
window.onload
(при загрузке страницы) с помощью функции observe
, которую добавляет обьекту document PrototypeJS. observe
добавляет к событиям, которые уже могли были быть связаны с событием window.onload
, указанное нами событие. Старайтесь пользоваться функциями addEventListener, observe (PrototypeJS) или $(window).load, чтобы предотвратить замещение уже «навешенных» на элемент функций.Таким образом я выполнил и первый пункт в списке улучшений.
Выводы
На мой взгляд, такое использование JavaScript, а именно — вынос всех функций на JS в отдельный файл и связывание этих функций с элементами страницы с помощью различных событий (здесь мы видели события
window.onload
и element.onclick
) — это на данный момент — единственно правильное использование JavaScript.Дерзайте, господа. :)
PS. Я прекрасно знаю, что можно использовать событие не
window.onload
, а DOMContentLoaded
. Но я считаю, что для примера понятнее будет всё же использование window.onload
.PPS. Кросспост отсюда.