меню

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

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

Эта проблема касается не только 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

Помощь сайту
ЮMoney:
4100 1180 7209 833
Карта Сбербанк:
2202 2080 6183 7127
MindForge: Pull Request наставник для GitHub
MindForge: Pull Request наставник для GitHub
Превратите свой пет-проект в эффективный тренажёр роста

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

Javascript array шпаргалка

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

Управление версиями Node.js с помощью nvm в Windows

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

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

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

Что такое ECMAScript и чем это отличается от JavaScript

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