views:

49

answers:

3

I'm working on a jQuery plugin that can be applied to multiple elements. The plugin includes some animation effects and I need to manage the event queue based on if the plugin is used on multiple elements (instead of one).

What's the best way to detect if the plugin has been applied to a single element or to multiple elements?

Edit...

The length property works correctly if the plugin is passed multiple elements (such as $('.myClass').plugin()) but if the plugin is called on multiple, single elements (such as $('#myElem1').plugin() and $('#myElem2').plugin()) then the length returns one for each call.

Is there are a way to detect multiple instances when the plugin is used as in the second example/

+2  A: 

this inside the plugin, depending on your style, refers to the jQuery object, so you can just check the .length property, for example:

 jQuery.fn.plugin = function(options) {
   if(this.length > 1) //being applied to multiple elements
 };

For your edit: tracking the total may be a better option, for example:

(function($) {
  $.pluginCount = 0;
  $.fn.plugin = function(options) {
    $.pluginCount += this.length;    //add to total
    if($.pluginCount > 1) //overall being applied to multiple elements
  };
})(jQuery)
Nick Craver
+1  A: 

Assuming you apply your plugin by $('some selector').myPlugin(), the "this" keyword will refer to the jquery object you've called the plugin on inside your plugin function.

So, to summarize:

(function( $ ){
  $.fn.myPlugin = function() {
    if(this.size() > 1) {
       //code for multiple elements
    }
    else if(this.size() == 1) {
       //code for 1 element
    }
  }
})( jQuery );

$('div.to-pluginize').myPlugin();
Alexander Malfait
A: 

If you want a generic way to test whether or not a plugin has been applied to a arbitrary set of elements, here is one approach:

// say we want to apply this to a bunch of elements
​​$.fn.test = function(str) {
    this.each(function() {
        // set a boolean data property for each element to which the plugin is applied
        $(this).data('test', true);
        alert(str);
    });
};


// use a simple plugin to extract the count of a specified plugin
// from a set of elements
$.fn.pluginApplied = function(pluginName) {
    var count = 0;
    this.each(function() {
        if($(this).data(pluginName)) {
            count++;
        }
    });
    return count;
};

with this markup:

<a href="test" class="test">Hello</a>
<br />
<a href="test" class="test">Hello</a>

Here is a test:

$("a").test('test');

alert($("*").pluginApplied('test'));​​​​​​​​​​​​​​​​ // alerts '2'

Demo: http://jsfiddle.net/B5QVC/

karim79