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?
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.
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 −
// 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.
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”>.
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 ));
}
});
}
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With