Несколько слов о Drupal.Behaviors и $(document).ready()
Сегодня неизвестный, но бдительный пользователь вновь напомнил мне о разнице между Drupal.behaviors и $(document).ready(). Причем так напомнил, что я уже обновил по горячим следам jSlider Form API. Для закрепления, напишу об этой разнице несколько слов.
Дело в том, что некоторые (и я был в их числе) принимают Drupal.behaviors за полную замену $(document).ready(), дескать, в Друпале надо вот так — и все. Виной тому, с одной стороны, невнимательность, с другой — тот факт, что в 2009-м году описание Drupal JavaScript API было не таким подробным, как теперь. Так или иначе, основная разница между ними заключается в том, что, тогда как $(document).ready() вызывается однократно, после готовности DOM, Drupal.behaviors может вызываться несколько раз: если скрипты подгружают по AJAX на страницу новые элементы и вызывают для них функцию Drupal.attachBehaviors().
При отладке с этим сталкиваешься не всегда, поэтому о разнице нетрудно забыть. Но в боевом режиме вляпаться легко. Достаточно поставить какой-нибудь Vote Up/Down — и вот уже кнопки, генерируемые нашими скриптами, при каждом голосовании генерируются вторично, а формы начинают сохраняться по несколько раз подряд.
Чтобы избежать таких глюков, необходимо в Drupal.behaviors, во-первых, использовать переменную context, и во-вторых — присваивать обработанным однажды элементам соответствующий класс и проверять его наличие при обработке. Как в данном примере, добавленном к упомянутому описанию JS в Друпале:
$('.module-class-object:not(.module-class-processed)', context).each(function () {
$(this).addClass('module-class-processed');
// Do things
});
};
Кроме того, для глобальных задач (например, однократно добавить на страницу кнопку) можно по-прежнему пользоваться
$(document).ready().
Ещё по этой теме хочу добавить что в Drupal7 вообще убрали переменную $, поэтому всякие $('div').hide() уже не работают, нужно всё делать с прямым указанием JQuery.
И исходя из примеров в других модулях, насколько я понял рекомендовано делать как-то так:
<?php Drupal.Mysite = {};
Drupal.Mysite.FormatMore = function() {
$('li.hidelink').hide();
}
$(Drupal.Mysite.FormatMore);
} ?>
Странно это все.
Но я с JS еще в семерке не работал.
И исходя из примеров в других модулях, насколько я понял рекомендовано делать как-то так:
<?php Drupal.Mysite = {};
Drupal.Mysite.FormatMore = function() {
$('li.hidelink').hide();
}
$(Drupal.Mysite.FormatMore);
} ?>
Посмотрите документацию на drupal.org. http://drupal.org/node/756722 - раздел Using jQuery
Теперь используется closure - замыкания.
// All your code here
}(jQuery));
В 6-ке тоже желательно использовать такую конструкцию
(function ($) {
// All your code here
}(jQuery));
это не замыкания, а self-invoking функция; замыкания - это немного другое
а вообще сама идея юзать эту конструкцию правильная












Да еще подметил такой факт, что Drupal.behaviors подключат все определенные в нем обьекты первее чем $(document).ready(). Как то провозился с такой осебенностью целый день.