Back-End

16 abr, 2013

Evitando ações duplicadas no Javascript do seu Drupal 7

Publicidade

Você já deve ter passado por aquela situação em que seu Javascript está se comportando de maneira estranha e está sendo executado várias vezes, sem nenhuma lógica.

Inicialmente, para criar um Javascript da maneira correta dentro do Drupal 7, você deve criar um novo arquivo js, com um behavior (comportamento), e esse é rodado automaticamente no ready do Dom, seguindo a ordem de execução dos módulos. Apesar de rodar somente quando o Dom está totalmente carregado, ele não é um puro substituto para o jQuery.ready, pois os behaviors podem rodar múltiplas vezes durante uma única execução.

Abaixo um exemplo:

meu_modulo.js

(function ($) {
  Drupal.behaviors.funcao_meumodulo = {
    attach: function(context, settings) {
      $('a.seletor', context).click(function(){
        $('.slider').slideToggle();
      });
    }
  };
})(jQuery);

Nesse caso, a funcao_meumodulo é o namespace, e deve ser único, para não ser sobrescrito ou até mesmo estendido. O parâmetro context é exatamente o conteúdo carregado na execução corrente, e o settings são variáveis e configurações setadas no Drupal/PHP, via drupal_add_js() ou diretamente no JS, através do Drupal.settings.meumodulo.

Agora, o ponto é que os behaviors do Drupal são automaticamente reaplicados a qualquer chamada Ajax; então, se você criou uma simples função para abrir e fechar um conteúdo na sua página, ele pode rodar várias vezes de acordo com a quantidade de chamadas Ajax que sua página já teve naquela execução.

Bom, para resolver isso o Drupal 7 tem por padrão o plugin jQuery Once, que resolve esse problema de uma ver por todas.

(function ($) {
  Drupal.behaviors.funcao_meumodulo = {
    attach: function(context, settings) {
      $('a.seletor').once('meuslider', function() {
        $('a.seletor').click(function(){
          $('.slider').slideToggle();
        });
      });
    }
  };
})(jQuery);

Com isso, o javascript colocará uma classe meuslider-processed no elemento a.seletor, evitando assim que o mesmo rode várias vezes numa mesma execução.