3

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" ?

Diego Dorado
  • 398
  • 4
  • 12

1 Answers1

2

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);
      });
    });
}
Community
  • 1
  • 1
jantimon
  • 36,840
  • 23
  • 122
  • 185
  • Your answer is quite correct... maybe i simplified too much my example, since i'd like to do something more complicated than alert the number of instances... i'll edit my question – Diego Dorado Aug 11 '12 at 20:56
  • See my updated answer. It allows to do what ever you like with your shared instances :) – jantimon Aug 11 '12 at 21:05
  • @DiegoDorado I added your "hide all parents" example. – jantimon Aug 11 '12 at 21:09
  • thank you for your help... maybe I was already tired... anyway, I ended up defining "classes" to acomplish what i needed. I realised that there was no point making a plugin if it wasnt solving a common purpose but rather a specific application need – Diego Dorado Aug 11 '12 at 22:29