Drupal.behaviors vs $(document).ready() в Drupal 7

Многие разработчики при написании javascript сценариев для своих модулей используют стандартную конструкцию jQuery $(document).ready() для исполнения своего кода после того как DOM дерево станицы полностью построено.

Такой подход допустим, но более правильно использовать специальную обертку Drupal.behaviors.
Шаблон ее следующий:

(function($) {
  Drupal.behaviors.UNIQUE_FUNCTION_NAME = {
    attach: function (context, settings) {
      //Сюда пишем свой код
    }
  };
})(jQuery);

Вместо UNIQUE_FUNCTION_NAME подставляем уникальное имя функции, лучше подбирать имя походящее по смыслу к тому что делает скрипт.

Преимущества этого подхода следующие:

  • У каждого скрипта свое пространство имен что предотвратит конфликт имен переменных и функций объявленных в других скриптах
  • Если на странице есть AJAX, скрипт объявленный через Drupal.behaviors будет выполнятся при каждой AJAX загрузке
  • В одном файле можно объявить несколько Drupal.behaviors функций разбив функционал на логические части

Первый раз все Drupal.behaviors функции выполняются при загрузке страници, при этом в переменную context попадает объект document, при каждом AJAX запросе Drupal.behaviors функции снова выполняются, но в перменную context попадает уже не вся страница, а только загруженный контет. Таким образом можно объявить обработчики событий для подгруженного контента используя функцию jQuery с контекстом $([selector], context);.

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

(function($) {
  Drupal.behaviors.UNIQUE_FUNCTION_NAME = {
    attach: function (context, settings) {
      if (typeof(init) == "undefined") {
        //Код написанный здесь будет выполнен
        //только один раз при загрузке страници
      }
      init = ture;
      //Код написанный здесь будет выполнен
      //при каждом AJAX запросе
    }
  };
})(jQuery);

Логика тут простая при первом вызове переменаня init еще не определена, поэтому функция typeof вернет для нее "undefined". такоим образом код инициализаци будет выполнен только первый раз при загрузке страници.

Еше одним полезным свойством которым обладают Drupal.behaviors функции это возможность вызвать их для любого jQuery набора воспользовавшись функцией Drupal.attachBehaviors(contentSet);, contentSet в данном случае может быть любым jQuery набором.

Поделись с друзьями:

Комментарии

код инициализаци буедт = опечатки

Спасибо, исправил :)

Денис, приветствую. Использую предложенное тобой решение. Работает, но есть минус который портит все. Когда заходишь на административные страницы- появляется ошибка в скрипте, который я таким образом обернул, и соответственно все остальные скрипты также отключаются, а это и редактор текста, пропадают вкладки, ну вобщем все, что использет скрипты. Есть мысли как решить эту проблемку?

Нашел решение. Ошибка возникала, когда для подключения скрипта к модулю использовал функцию drupal_add_js(). Ошибка перестала выскакивать, когда подключение сделал через $form['#attached']['js'].