tl; dr : o código JavaScript para processar elementos no carregamento da página em um site Drupal 7 deve ser semelhante a este:
(function($) {
Drupal.behaviors.doSomething = {
attach: function(context, settings) {
$('div.something', context).once('do-something').doSomething({
param1: settings.somethingl.param,
param2: 'something else'
});
}
}
})(jQuery);
O Drupal 7 fornece jQuery no modo sem conflito , o que significa que $
não é o objeto / namespace jQuery. Isso não deve ser um problema com plug-ins jQuery escritos corretamente que seguem as diretrizes de criação de plug-ins jQuery . No entanto, isso é um problema para snippets de código copiados / colados sem pensar de páginas da Web aleatórias. Como a maioria deles espera $
ser o namespace jQuery. Isso pode ser facilmente resolvido envolvendo esses snippets em uma função anônima imediatamente invocada que criará o alias do namespace jQuery para $
:
(function($) {
// Here $ is the jQuery namespace.
})(jQuery);
Normalmente, o código JavaScript que precisa ser executado no carregamento da página também é encapsulado em uma função passada como argumento para jQuery
ou jQuery(document).ready
:
$(function() {
// Code here is executed when the DOM is loaded.
});
Quando combinados, esses dois padrões são perfeitamente bons, mesmo com o Drupal. No entanto, se o conteúdo (ou seja, novos elementos DOM) for adicionado à página após o carregamento da página (chamadas AJAX, conteúdo gerado de JavaScript, etc.), o código em tais funções nunca será capaz de processar os elementos adicionados. Ou se alguma parte do conteúdo for removida ou movida pela página, o código não terá a opção de cancelar o registro de manipuladores de eventos ou atualizar as informações sobre os elementos já processados. O Drupal fornece uma API para esses comportamentos chamados . Usar o comportamento não é obrigatório, mas é altamente recomendado como melhor prática para evitar dores de cabeça futuras (quando o código escrito seis meses atrás começa a se comportar de forma estranha quando um módulo contrib é adicionado ao projeto). Um comportamento é escrito assim:
Drupal.behaviors.behaviorName = {
attach: function (context, settings) {
// Do something.
},
detach: function (context, settings, trigger) {
// Undo something.
}
};
A attach
função de todos os comportamentos registrados (todas as propriedades do objeto) será chamada quando o comportamento deve ser adicionado aos elementos, seja quando o DOM estiver pronto (ou seja, página laod) e quando os elementos forem adicionados ao DOM. A função será chamada quando os comportamentos devem ser separados dos elementos: logo antes de os elementos serem removidos do DOM, movidos no DOM ou um formulário ser enviado. O parâmetro sempre será um pai dos elementos adicionados, o próprio elemento adicionado / removido / movido ou o elemento. Os parâmetros serão as configurações para o , geralmente o objeto definido por chamadas a partir do PHP. Para , o parâmetro conterá o tipo de evento que acionou a chamada:Drupal.behaviors
detach
context
document
settings
context
Drupal.settings
drupal_add_js()
detach
trigger
'unload'
(elementos removidos), 'move'
(elementos movidos) ou 'serialize'
(o formulário está sendo enviado).
As funções attach
(e detach
) de um comportamento podem ser usadas várias vezes na mesma parte da árvore DOM. Portanto, o mesmo elemento pode ser processado várias vezes pelo mesmo código. É responsabilidade do próprio código evitar o processamento (ou seja, vinculando manipuladores de eventos, alterando estilos CSS, etc.) várias vezes para os mesmos elementos. A solução mais fácil para isso é usar o plugin jQuery Once (que é fornecido pelo Drupal 7 ) assim:
$(selector).once('behavior-name').doSomething();
$(selector).once('behavior-name', function(){ /*do something*/ });
Uma vez que um comportamento está sendo anexado / desanexado de / para um contexto, o objeto de contexto pode ser usado para restringir suas consultas jQuery apenas ao elemento afetado ou subárvore DOM, como este:
$ (seletor, contexto) .doSomething ();
Juntar tudo isso significa que o padrão básico para processar os elementos no carregamento da página deve ser assim:
(function($) {
Drupal.behaviors.doSomething = {
attach: function(context, settings) {
$('div.something', context).once('do-something').doSomething({
param1: settings.somethingl.param,
param2: 'something else'
});
}
}
})(jQuery);
Referências: