JavaScript, jQuery e DOM Ready no Drupal 7

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 jQueryou 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 attachfun√ß√£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.behaviorsdetachcontextdocumentsettingscontextDrupal.settingsdrupal_add_js()detachtrigger'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: