Diego Dorado
Diego Dorado

Reputation: 398

How to share properties and functions between jquery plugin instances?

I'd like to share properties and methods between a jquery plugin instance ( one i create) How would i do that properly?

Supose i have a simple plugin defined as:

// add the plugin to the jQuery.fn object
$.fn.clickableImage = function(options) {

    this.set_not_clicked = function(){
      return this.each(function() {
        $(this).addClass('not-clicked');
      });

    };

    // iterate through the DOM elements we are attaching the plugin to
    return this.each(function() {
      $(this).click( function(){
        parent.set_not_clicked() //how to get "parent" ???
        $(this).removeClass('not-clicked').addClass('clicked');
      });
    });
}

And, images instanciated as:

$(function(){
  $('#some-selector img').clickableImage();
});

How to make an "clickableImage" aware of others "clickableImage" ?

Upvotes: 3

Views: 1297

Answers (1)

jantimon
jantimon

Reputation: 38142

Closures are a common pattern in javascript because they prevent the global name space pollution.

See this SO question for details: What exactly does "closure" refer to in JavaScript?

A "closure" is an expression (typically a function) that can have free variables together with an environment that binds those variables (that "closes" the expression).

In your case this would look like this:

(function($){
   var instances = [];
   function count(){
     alert(instances.length);
   }

   function hide_parent(){
     for(var i=0;i<instances.length;i++){
       $(instances[i]).parent().hide();
     }
   }

   $.fn.clickableImage = function(options) {

    // Use a class to prevent double bindings.       
    this
     .filter(':not(.clickImage)')
     .addClass('clickImage')
      // iterate through the DOM elements we are attaching the plugin to
     .each(function() {
        instances.push(this);
        $(this).click( function(){
          // Alert the current image count:
          count(); 
          // Hide all parents:
          hide_parent();
        })
      })

    return this;
  }
}(jQuery));

alert(typeof instances);// will return undefined

You could also add a class and search the dom for your class:

$.fn.clickableImage = function(options) {
    // iterate through the DOM elements we are attaching the plugin to
    return this
      .addClass('clickImage')
      .each(function() {
      $(this).click( function(){
        $("img.clickImage").each(function(){
          $(this).parent().hide();
        });
        alert(instances_count);
      });
    });
}

Upvotes: 2

Related Questions