Проверка типа контекста в javascript

7 октября 2010 в 22:38

Добрый вечер

думаю, многие из вас знакомы со стандартами написания javascript для друпала, в частности с механизмом behaviors.
Как известно, грамотно написанный js-код заключается в конструкцию типа Drupal.behaviors.yourModule = function(context) { ... } и вызывается друпалом или другими модулями конструкцией типа Drupal.attachBehaviors(context);, где context — это контекст вызова. Как правило, это windows.document, т.е. в качестве контекста мы имеем целый документ. Но бывает так, что attachBehaviours вызываются сторонними модулями (и это очень хорошо и удобно), а в качестве контекста они передают, скажем, DOM элемент. Я хотел узнать, каким образом вы определяете тип объекта, переданного в качестве контекста. Мне на ум пока приходит только проверка одного из свойств объекта на существование, но это смахивает на костыли.

Комментарии

К примеру, модуль openlayers инициализирует карту после того, как мой js уже был приаттачен друпалом и отработал.
Благо, openlayers вызывает Drupal.attachBehaviors(...) еще раз после инициализации каждой карты. Благодаря этому, в своем js я могу произвести нужные операции с картой (которые невозможно было сделать при первом аттаче моего скрипта, т.к. объект карты на этом этапе еще не существует). OpenLayers при attachBehaviors передает в качестве контекста DOM элемент, содержащий карту, сам объект карты передается с помощью jQuery.data(). Вот я и искал удобный способ проверки типа контекста. В общем-то, уже нашел — можно проверять свойства nodeName (#document в первом случае и DIV во втором) или nodeType (там числовые коды, расшифровка есть вот здесь http://www.javascriptkit.com/domref/nodetype.shtml)

Кстати, полезный совет:
Если js-код модуля обернут в Drupal.behaviors.yourModule = function(context) { ... }, то он может быть вызван несколько раз в течение загрузки страницы, и могут возникнуть нежелательные последствия, поскольку ваш код будет выполнен дважды (что само по себе уже не очень хорошо).
Я как-то столкнулся с тем, что после установки модуля, который использовал attachBehaviors, сайт стал зависать, да так, что приходилось перезагружать машину. Оказалось дело в том, что один из моих скриптов был вызван дважды и во второй раз отрабатывал не так, как предполагалось, т.к. на тот момент DOM-дерево уже было изменено им же при первом запуске.

С тех пор использую вот такую обертку для всех скриптов:

Drupal.behaviors.myModule = function(context) {
 
  if ( Drupal.behaviors.myModule.initState === undefined ) {
   
    Drupal.behaviors.myModule.initState = true;
   
    ...
   
    // Code here
   
    ...
   
  }

}

8 октября 2010 в 1:25

Вот что обычно используется для избежания дублей в поведениях:

Drupal.behaviors.mymodule = function(context) {
  $('#mymodule-element:not(.mymodule-processed)', context).addClass('mymodule-processed').each(function() { ... });
}

Может это поможет решению вашей проблемы?

9 октября 2010 в 7:52

neochief wrote:
Вот что обычно используется для избежания дублей в поведениях:

Drupal.behaviors.mymodule = function(context) {
  $('#mymodule-element:not(.mymodule-processed)', context).addClass('mymodule-processed').each(function() { ... });
}

Может это поможет решению вашей проблемы?

Спасибо, возьму на заметку. Хотя, на мой взгляд, тяжеловатый код, но для некоторых ситуаций оправдан.

27 октября 2010 в 2:13

Stutzer wrote:
neochief wrote:
Вот что обычно используется для избежания дублей в поведениях:

Drupal.behaviors.mymodule = function(context) {
  $('#mymodule-element:not(.mymodule-processed)', context).addClass('mymodule-processed').each(function() { ... });
}

Может это поможет решению вашей проблемы?

Спасибо, возьму на заметку. Хотя, на мой взгляд, тяжеловатый код, но для некоторых ситуаций оправдан.


А что в нем такого тяжелого? По сравнению с другими решениями это просто няшка )

27 октября 2010 в 15:21

neochief wrote:
Он наиболее правильный с позиции идеологии прицепки поведений в JS Друпала.

Когда наш скрипт производит манипуляции с DOM-элементами, то да — это, пожалуй, самый верный способ.

<a href="mailto:v1adimir@drupal.org">v1adimir@drupal.org</a> wrote:
А что в нем такого тяжелого? По сравнению с другими решениями это просто няшка )

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

28 октября 2010 в 0:22
Аватар пользователя W32 W32 0

И мне подскажите пожалуйста.
Я не использую какой-либо модулю, весь мой код находится в php снипете. Но этот код добавляет js скрипт (галерейка на jQuery) в страницу и он должен обработатся как положено. В каком виде я должен оформить Drupal.behaviors. ? Ведь модуля никакого у меня нет.

P.S. меня интересует формат для D7

21 февраля 2011 в 18:07