Drupal 7 Prevent Duplicating JavaScript Behaviors

By shane
Mon, 2012-09-10 11:24
comments

Share with Others

You may have run into a situation in Drupal 7 in which you only need to apply a JavaScript behavior one time. In most cases your JavaScript seems to be executing fine, however you might notice that sometimes things seem to be executing two times or more. This may be getting triggered by some type of AJAX call that causes your JavaScript behaviors to get executed again. In this post we will examine how we can prevent these duplicate behaviors from being applied by using a very simple example.

You may also be looking for How to Add JavaScript to your Drupal 7 Module.

Simple Duplicate JavaScript Behavior Example

First we will look at a small piece of HTML. This is just a simple h3 element with a div. The goal is to have the div expand when the h3 element is clicked (there are many reasons why this is not the best approach for achieving this functionality, but this will be suitable for a simple example).

<h3 class="slider-trigger">Slider Trigger</h3>
<div class="slider">This is my slider text. This text will automatically expand when the Slider Trigger is clicked</div>

Now we add our JavaScript:

(function ($) {
  Drupal.behaviors.myCustomJS = {
    attach: function(context, settings) {
 
      $('h3.slider-trigger').click(function(){
        $('.slider').slideToggle();
      });
    }
  };
})(jQuery);

Now in most cases this would work great. However, if you have something that makes an AJAX call and the JavaScript behaviors get applied again. Then you may end up with a situation in which clicking the Slider Trigger h3 element, will cause the slider text to open and close, thus duplicating the sliding behavior. This is obviously an issue, luckily Drupal 7 makes it easy to fix.

Solution: Using Jquery Once

Drupal 7 integrates the Jquery Once plugin into Drupal 7 core. This plugin adds a simple class to the HTML element to ensure that the behavior is only processed one time. Here is how we would modify our JavaScript to work with the Jquery Once plugin.

(function ($) {
  Drupal.behaviors.myCustomJS = {
    attach: function(context, settings) {
      $('h3.slider-trigger').once('myslider', function() {
        $('h3.slider-trigger').click(function(){
          $('.slider').slideToggle();
        });
      });
    }
  };
})(jQuery);

This JavaScript will now add a myslider-processed class to the h3 slider-trigger element to ensure the Jquery Click handler is only added one time.

Do you have any other examples of when this has been useful? If so, leave them in the comments below.