Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does a jQuery plugin load a collection of elements?

I'm not sure if this is a stackoverflow question since it is kind of general so forgive me if it is.

Lets say I have the following markup:

<div class="plugin"> ... </div>
<div class="plugin"> ... </div>
<div class="plugin"> ... </div>

And I wan't to run a jquery plugin and pass it every element that has the plugin class:

$(".plugin").myPlugin();

Plugin code looks something like this:

;(function ( $, window, undefined ) {

  var myPlugin = 'myPlugin',
      document = window.document,
      defaults = {
        propertyName: "value"
      };

  // The actual plugin constructor
  function Plugin( element, options ) {
    this.element = element;

    this.options = $.extend( {}, defaults, options) ;

    this._defaults = defaults;
    this._name = myPlugin;

    this.init();
  }

  Plugin.prototype.init = function () {

  };

  // A really lightweight plugin wrapper around the constructor, 
  // preventing against multiple instantiations
  $.fn[myPlugin] = function ( options ) {
    return this.each(function () {
      if (!$.data(this, 'plugin_' + myPlugin)) {
        $.data(this, 'plugin_' + myPlugin, new Plugin( this, options ));
      }
    });
  }
}(jQuery, window));

When I run this code it looks like the plugin constructor is being called for each element that has the class name of myPlugin. I thought that it would run the plugin on the entire collection of divs and only call the constructor once.

So how does it work? Is an instance of the plugin created for each of the elements returned by the class selector?

like image 869
Stephen__T Avatar asked Jan 07 '13 00:01

Stephen__T


People also ask

What is a jQuery plug-in?

jQuery - Plugins - A plug-in is piece of code written in a standard JavaScript file. These files provide useful jQuery methods which can be used along with jQuery library methods.

How to include jQuery plug-in file in the document?

To make a plug-in's methods available to us, we include plug-in file very similar to jQuery library file in the <head> of the document. We must ensure that it appears after the main jQuery source file, and before our custom JavaScript code. Following example shows how to include jquery.plug-in.js plugin −

What is a jQuery collection?

// Open popup code. // Close popup code. Your typical jQuery object will contain references to any number of DOM elements, and that's why jQuery objects are often referred to as collections.

How to iterate through a collection of elements using jQuery?

The jQuery.each method is the go-to tool when you need to iterate a collection of DOM elements. Let’s say you have a bunch of elements in the page. Maybe that bunch is “ every <a> tag ” or “ every <li> inside of the <ul> with the class sales ”, or each <div> element that is a child of <div class=”members”>.


2 Answers

Maybe following comments will help:

$.fn[myPlugin] = function ( options ) {
    /* "this" is collection of elements from selector*/
    return this.each(function () {
        /* "this" is individual element due to being inside "each" loop*/
      if (!$.data(this, 'plugin_' + myPlugin)) {
        $.data(this, 'plugin_' + myPlugin, new Plugin( this, options ));
      }
    });
  }
like image 130
charlietfl Avatar answered Nov 15 '22 10:11

charlietfl


From the top

$(".plugin").myPlugin();

jquery selector

jQuery will take the selector .plugin and then run its usual selection process, generating a jQuery object (with the jQuery prototype available for chaining) which also contains the length of the results, an array of the results, and the selector used.

so, $(".plugin") returns this object with the aforementioned contents.

myPlugin()

myPlugin() is a function call. It is made against the jQuery prototype which was returned from $(".plugin"). This function is located where it was defined: $.fn[myPlugin]. fn is jQuery's way of adding in functionality to its base prototype. Note that this is only called once.

$.fn[myPlugin] = function

The function called here now runs. It runs on this, which was the original jQuery object mentioned above (including the array of results from the selector). this.each(function () {...}, where jQuery's each function will iterate through the results from the jQuery object. In the case of your example, there are 3 divs.

each iteration runs

if (!$.data(this, 'plugin_' + myPlugin)) {
 $.data(this, 'plugin_' + myPlugin, new Plugin( this, options ));
}

The first line is a conditional statement which looks to see if the data object named "plugin_myPlugin" (myPlugin is a constant string value) exists on the current element (which is one of those 3 divs). None of them has this when this code is ran first.

$.data(this, 'plugin_' + myPlugin, new Plugin( this, options ));

This line of code takes the this object, which is the current html element, passes it to jQuery's data method, which adds an object to the element indexed by the name. The name in this case is "plugin_myPlugin", and the object is...

new Plugin( this, options )

Plugin is a function defined locally to the $.fn[myPlugin] scope in your example. It is defined as function Plugin( element, options ) {...}.

function Plugin( element, options ){...}

This function will take an element, which was passed from the iteration in each - in this example one of the 3 divs - and the options which were originally sent in as an argument for $.fn[myPlugin] (in this case there were none passed in, as can be seen with myPlugin().

The function takes these arguments, and builds them onto the current Function object using this.element, this.options, this._defaults, and this._name, and then calls the init function (which is empty here).

After all that a Function object is constructed, and then is attached using jQuery's data method to the current element.

Executive Summary

The extended function myPlugin will run once for each element in the jQuery object generated from the selector used. The extended function creates a new Function object from the defined function Plugin for each element eligible (thus running the constructor on each one, 3 times in this exact example).

like image 44
Travis J Avatar answered Nov 15 '22 08:11

Travis J