На разного рода форумах, я встречал и встречаю однотипные ошибки, которые допускают новички при работе с библиотекой jQuery и из-за которых их код работает не правильно или вообще не работает. Поэтому, я решил написать статью-шпаргалку, которая поможет исправить свои недочеты самостоятельно или избежать ошибок в будущем.
Консоль должна быть открыта. Закрытая консоль, конечно же, не ошибка в коде, однако, ошибочный подход во время отладки сценария. Именно консоль поможет быстро сориентироваться в том, где и какая допущена ошибка, а также следить за ходом выполнения сценария. Во всех современных браузерах - этот инструмент присутствует по умолчанию. Например, в FireFox консоль можно вызвать с помощью сочетания клавиш Ctrl + Shift + K или "Меню" > "Разработка" > "Веб-консоль". В Chrome вызывается сочетанием клавиш Ctrl + Shift + J или "Меню" > "Дополнительные инструменты" > "Консоль JavaScript". В Opera - сочетание клавиш аналогичны Chrome, вызов из меню - "Инструменты разработчика" > "Веб-инспектор" ("Инструменты разработчика" предварительно включить в пункте "Другие инструменты"). Кроме того, существуют инструменты/аддоны, как, например, замечательный FireBug под FireFox или Web Developer для Chrome и этот же инструмент для FireFox
Не подключена библиотека. У кого-то этот пункт вызовет улыбку, но могу вас уверить, что по моей личной статистике, как минимум раз в месяц, на форуме появляется вопрос о том, почему ничего не работает, а после долгих выяснений оказывается, что js-файл с библиотекой просто не подключен на странице. Библиотека jQuery должна быть по возможности новее, подключена первой, до скриптов, в которых она используется и в единственном числе. Если вы используете какой-нибудь старенький плагин, которому для работы требуется такая же старая версия jQuery, то есть несколько нормальных путей решения, чем подключение на страницу и новой библиотеки и старой для плагина:
- Оставляем одну новую библиотеку и сразу после неё подключаем плагин jQuery Migrate, который, в большинстве случаев, помогает решить вопрос совместимости.
- Без каких-либо дополнений, сами заменяем в плагине удаленные методы на их современные аналоги. Обычно, это такие устаревшие или удаленные методы, как live(), $.browser и т.д.
- И конечно же, можно найти современный аналог плагина, который вам понравился. Не зацикливайтесь на одном.
Ну, и примерный порядок подключения:
<script src="/js/jquery-1.11.1.min.js"></script><!-- библиотека jQuery -->
<script src="/js/jquery-migrate-1.2.1.min.js"></script><!-- если требуется -->
<script src="/js/jquery-ui.min.js"></script><!-- если используете jQuery UI -->
<script src="/js/my_scripts.js"></script><!-- ваши коды -->
Код не обернут в конструкцию DOM-Ready. Одна из наиболее популярных ошибок. Если ваш скрипт расположен/подключен в теге <head>, то его нужно обязательно заключить в такой код:
$(document).ready(function(){
// тут весь ваш код
});
// или сокращенная запись
$(function(){
// тут весь ваш код
});
Это так называемый "обработчик готовности дерева DOM". Попробую "на пальца" и простым языком объяснить, что это и зачем нужно. Браузер загружает страницу, начиная с первого на ней элемента и движется вниз. Всё, что подключено в теге <head>: CSS, JS и т.д., загрузится и начнёт выполняться раньше, чем дело дойдёт до элементов, которые находятся в <body>. Поэтому, при обращении к элементу из JS-кода, его еще попросту нет на странице. А обёртка, которую я показал выше, откладывает выполнение сценария до тех пор, пока вся структура страницы не будет загружена браузером полностью. Как вариант, который совсем не лишён логики и даже рекомендуется тем же Google, весь свой код можно расположить в конце страницы, перед закрывающим тегом </body>. Так же, хоть и не совсем по теме этого пункта, рекомендуется в некоторых случаях использовать атрибут async для тега <script>.
Не используется делегированная обработка событий для динамических элементов. Этот случай знаком многим, кто использует технологию Ajax. Пунктом выше, мы затронули тему DOM и доступностью элементов при загрузке страницы, но что делать, если элементы добавляются динамически и с ними нужно работать так же, как и со статичными? Вот тут на помощь приходит делегированная обработка событий. Синтаксис:
$('static_parent').on('event', 'dinamic_child', handler);
- static_parent - статичный родительский элемент
- event - событие
- dinamic_child - динамический дочерний элемент
- handler - функция-обработчик
К примеру, в каком-то блоке с классом "my_block", есть несколько ссылок с классом "my_link", при клике на которые, выполнялось какое-то действие. Все они изначально присутствовали при загрузке страницы. Теперь мы добавили еще несколько ссылок с таким же классом, но без делегированной обработки, они будут просто проигнорированы и нужное действие уже не выполнится. Для того, чтоб событие обрабатывалось и на старых, и на новых ссылках, нам нужно записать так:
$('.my_block').on('click', '.my_link', function(){
// действия при клике
});
! При чём, объект $(this) внутри обработчика - это именно ссылка ".my_link", на которой событие было вызвано, а не родительский элемент ".my_block", как это бы было при обычной записи, а не делегированной. Старайтесь находить ближайший родительский статичный элемент, что ускорит работу кода. Хотя, в качестве такого, можно выбрать и body, и даже document.
Неправильно подобранный селектор. Вообще, эта тема гораздо обширнее, чем звучит, но тут разберём самые основные промахи, которые допускают новички. Селектор, говоря образно, это признак элемента, по которому мы к этому элементу обращаемся или применяем какой-либо из методов. Селекторами в jQuery (и не только), может быть как имя тега, класс элемента (атрибут "class"), его идентификатор (атрибут "id"), так и любые другие атрибуты или же их комбинации. Тем, кто знаком с CSS, можно расслабится, т.к. селекторы jQuery строятся по такому же принципу, как и в CSS, а вот остальным придётся познакомиться с CSS поближе. Парочка примеров:
$('div'); // выберет все элементы "div"
$('#my_element'); // выберет единственный (*см. ниже) элемент с атрибутом id равным "my_element"
$('.my_element'); // выберет все элементы на странице с классом "my_element"
$('.my_element.other_class'); // выберет элементы на странице с классом "my_element", у которых так же есть класс "other_class"
$('#my_element .my_element'); // выберет все дочерние элементы с классом "my_element" у родительского с id = "my_element"
$('[name=my_name]'); // выберет элементы, у которых атрибут name равен my_name
$('[name=^my_name]'); // выберет элементы, у которых значение атрибута name начинается на "my_name"
$(':checkbox'); // выберет все элементы input с типом "checkbox"
// и так далее ...
Теперь о главной и критической ошибке всех новичков, связанной с селекторами... Возьмите себе за правило, повесьте в рамочке на самом видном месте, повторяйте как мантру перед сном: "В пределах одной страницы - не может быть два и более элементов с одинаковыми атрибутами ID"! Это правило не имеет никаких "а вдруг ..." или "а если ...". Поэтому, если вы очень удивлены тому, что на одном элементе событие срабатывает, а на втором таком же нет, то в первую очередь проверьте, а не попадают ли они под правило выше.
В этой статье точку не поставишь, поэтому следите за её обновлениями и не делайте ошибок или учитесь их исправлять ;)