меню

В очередной раз открыв код коллег и ужаснувшись, я решил написать эту статью. Надеюсь для кого-нибудь это будет полезным, заодно и мне будет проще новичкам объяснять что у них в коде не так, просто кинув ссылку на эту статью. Безусловно количество таких вещей очень и очень велико, поэтому в статье ограничусь лишь некоторыми.

Константы в коде

Эта проблема касается не только javascript, а программирования в целом. Рассмотрим пример:

  
$elem.on('keydown', function(e) {
    if (e.keyCode == 27) {
        //...
    }
});   
  

Что за магическое число 27? Люди, которые часто сталкиваются с кодами сразу скажут — это же клавиша ESC. Но большинство разработчиков, особенно начинающих, либо не помнят эти коды, либо не знают вообще, и сталкиваясь с кодами, вынуждены в очередной раз лезть в поисковую систему и тратить время.

Можно конечно добавить комментарий в коде, что это обработка нажатия клавиши ESC, но гораздо эффективнее было бы ввести константу, например, KEY_ESC = 27

Получение идентификаторов

Часто возникает необходимость получить идентификатор элемента (комментария, поста, пользователя и т.п.), чтобы выполнить какие-нибудь действия. (например, оценить комментарий при помощи ajax). И часто можно встретить подобный подход:

  
var id = $(this).attr('id').substring(8);   
  

Как и в предыдущем примере разработчику приходится гадать — что же это за число 8. Лезть в html код и т.п.

Бывают примеры и хуже (строчка скопирована с реального проекта):

  
var last_id = $('#answer_pid' + id + ' li:first div').attr('id').substr(7);   
  

Малейшее изменение верстки приведет к тому, что js код придется править.

Иногда бывает такое:

  
<div class="comment" id="comment_123"></div>

var id = $(this).attr('id').substring("comment_".length);   
  

Уже лучше (по крайней мере нет вшитых чисел), но все равно данный подход слишком сильно привязывает js код к html.

На мой взгляд гораздо лучше использовать data-* параметры, например

  
<div class="comment" data-id="123"></div>   
  

тогда получить идентификатор будет очень просто:

  
var id = $(this).attr('data-id');   
  

или

  
var id = $(this).data('id');    
  

(Про отличия в работе attr и data есть множество статей)

$.post

Как известно — в jquery есть метод для работы с ajax — $.ajax. К нему есть несколько shorthand функций, таких как $.get, $.load, $.post и т.п. Данные функции были добавлены специально, чтобы облегчить часто выполняемые действия (подгрузить скрипт, json, выполнить post запрос), но в реализации все эти методы ссылаются на $.ajax.

Лично я никогда не использую shorthand функции, и вот почему:

В коде начинающих или малоопытных разработчиков можно встретить несколько разных стадий:

Начальный

  
$.post(url, data, function(data) {
            data = $.parseJSON(data);
            //...
});   
  

Добавляется try catch блок

  
$.post(url, data, function(data) {
      try {
                data = $.parseJSON(data);
            } catch (e) {
                return;
            }
            //...
});   
  

Узнаем из документации, что в $.post последним параметром можно передать dataType (который пропадает в бездне кода, если success функция не влезает в экран).

  
$.post(url, data, function(data) {
    //...
}, 'json');   
  

Очень редко веб разработчики добавляют обработчики ошибочных ситуаций. В основном это происходит из-за лени, либо нежелании потратить лишние 5 минут времени, либо разработчики просто уверены, что ошибок никогда не будет.

Если же разработчик решил к $.post добавить обработчик ошибок, то получается нечто вроде:

  
$.post(url, data, function(data) {
    //...
}, 'json').error(function() {
   ///
});
  

На мой взгляд — это ужасно нечитабельно. Да и писать каждый раз обработчик ошибок — дело нудное, поэтому можно настроить обработчик ошибок по умолчанию для всех ajax запросов, например:

  
$.ajaxSetup({
    error: function() {
        //Показать окошко о том, что произошла ошибка
    }
});   
  

Вернемся к $.post. Как показано выше — использование $.post делает код ужасным (особенно с dataType в непонятном месте). Перепишем последний пример на $.ajax. На мой взгляд данный подход читабельнее и проще в поддержке.

  
$.ajax({
    type: "POST"
    url: url,
    data: data,
    dataType: "json",
    success: function(data) {
        //
    },
    error: function() {
        //
    }
});   
  

Обработчики событий к нескольким элементам

Часто бывает необходимость добавить обработчики событий к элементам страницы (например, кнопка «удалить сообщение»). И зачастую можно встретить подобный подход:

  
$('.comment a.delete').click(function(){
    //
});   
  

Возникает проблема — добавить этот же обработчик к новому элементу (например к динамески подгруженному комментарию). И тут я видел множество решений, включая переопределение всех обработчиков заново (нередко копипастом содержимого обработчиков):

  
$('.comment a.delete').unbind('click').click(function() {
    //
});   
  

Решение: в jQuery 1.7 есть метод on, который привязывает обработчики события, фильтруя элементы по селектору. пример:

  
$('body').on('click', 'a.external', function(e) {
  //функция будет вызвана при клике на любую ссылку с классом external
});   
  

При этом важно, что данный обработчик работает и для динамически создаваемых объектов.

Стоит также заметить, что данный подход нужно применять с умом. Например следующий код может привести к снижению производительности и подтормаживаниям браузера:

  
$('body').on('mousemove', selector, function() {
  //
});   
  

Namespaced events

Несмотря на то, что namespaced events были добавлены в jQuery 1.2 — ими мало кто пользуется (Мне кажется большинство людей просто не знают о них).

Рассмотрим пример:

  
$('a').on('click', function() {
  //обработчик 1
});
$('a').on('click', function() {
  //обработчик 2
}); 
  

Теперь предположим, что нам нужно удалить второй обработчик от ссылок. Но вот ведь незадача — $('a').off('click') удалит оба обработчика. На помощь приходит namespaced events.

Перепишем код выше:

  
$('a').on('click.namespace1', function() {
  //обработчик 1
});
$('a').on('click.namespace2', function() {
  //обработчик 2
});   
  

Теперь становится возможным удалить второй обработчик при помощи вызова $('a').off('click.namespace2');

Подробнее о namespaced events можно прочитать здесь: docs.jquery.com/Namespaced_Events


Возможно, вам будет интересно

Три способа понять промисы

Promise (обычно их так и называют «промисы») – предоставляют удобный способ организации асинхронного кода. В современном JavaScript промисы часто используются в том числе и неявно, при помощи генераторов.

Восемь типов данных и typeof

В JavaScript существует несколько основных типов данных. В этой статье мы получим о них общее представление, а позже, в соответствующих главах подробно познакомимся с использованием каждого типа в отдельности.

Определение платформы устройства на javascript

Определить версию и тип браузера проще всего при помощи JavaScript. JavaScript имеет стандартный объект под названием navigator, который содержит данные о браузере пользователя.

Вывод последнего дня текущего месяца на Javascript

Попалась интересная задачка, на баннере нужно было выводить «Акция действует до (тут последний день месяца)», решил сделать это на Javascript, ну чтоб не лазить каждый раз в код для правок, вот что получилось

Оформление заявки

Документы на создание сайта

Изучите наше коммерческое предложение, заполните БРИФ и отправьте его на почту maxidebox@list.ru. Изучив все пожелания из БРИФ-а, обратным ответом оповестим Вас по стоимости разработке, ответим на вопросы.

КП на создание сайта Коммерческое предложение на созданеи сайта

Мы берем на себя ответственность за все стадии работы и полностью избавляем клиентов от забот и необходимости вникать в тонкости.

Скачать БРИФ (акета) на создание сайта Скачать БРИФ (акета) на создание сайта

Зополните у БРИФ-а все необходимые поля. Сделайте краткое описание к каждому из пунктов анкеты, привидите примеры в соответсвующий пунктах - это позволит лучше понять Ваши ожидания и требования к сайту