jquery Plugin Development Full analysis
There are two types of jquery plugin development:
One is the development of a class-level plug-in that adds a new global function to jquery, which is equivalent to adding a method to the jquery class itself. The global function of jquery is a function that belongs to the jquery namespace, and the other is the object-level plug-in development that adds a method to the jquery object. The following is a detailed description of the development of the two functions.
1, class-level plug-in development
The most straightforward understanding of plug-in development at the class level is to add a class method to the jquery class, which can be understood as adding a static method. The typical example is $. The AJAX () function, which defines the function in the jquery namespace. Plug-in development at the class level can be extended in the following ways:
1.1 Adding a new global function
To add a global function, we just need to define the following:
JavaScript code
function() { alert(‘This is a test. This is only a test.‘); };
1.2 Adding multiple global functions
Add multiple global functions, which can be defined as follows:
JavaScript code
function() { alert(‘This is a test. This is only a test.‘); }; jQuery.bar = function(param) { alert(‘This function takes a parameter, which is "‘ + param + ‘".‘); }; 调用时和一个函数的一样的:jQuery.foo();jQuery.bar();或者$.foo();$.bar(‘bar‘);
1.3 Using Jquery.extend (object);
JavaScript code
jQuery.extend({ function() { alert(‘This is a test. This is only a test.‘); }, bar: function(param) { alert(‘This function takes a parameter, which is "‘ + param +‘".‘); } });
1.4 Using namespaces
Although in the jquery namespace, we prohibit the use of a large number of JavaScript function names and variable names. However, it is still inevitable that some functions or variable names will conflict with other jquery plugins, so we are accustomed to encapsulating some methods into another custom namespace.
JavaScript code
jQuery.myPlugin = { foo:function() { alert(‘This is a test. This is only a test.‘); }, bar:function(param) { alert(‘This function takes a parameter, which is "‘ + param + ‘".‘); } }; 采用命名空间的函数仍然是全局函数,调用时采用的方法: $.myPlugin.foo(); $.myPlugin.bar(‘baz‘);
With this technique (using a separate plug-in name), we can avoid collisions of functions within namespaces.
2, Object-level plug-in development
Plug-in development at the object level requires two forms:
Form 1:
JavaScript code
(function($){ $.fn.extend({ pluginName:function(opt,callback){ // Our plugin implementation code goes here. } }) })(jQuery);
Form 2:
JavaScript code
(function($) { $.fn.pluginName = function() { // Our plugin implementation code goes here. }; })(jQuery);
The above defines a jquery function, the parameter is $, and after the function definition is complete, the jquery argument is passed in. Call execution immediately. The advantage of this is that when we write a jquery plugin, we can also use this alias, without causing a conflict with prototype.
2.1 Declare a name under the jquery namespace
This is a single plug-in script. If your script contains multiple plugins, or reciprocal plugins (for example: $.fn.dosomething () and $.fn.undosomething ()), then you need to declare multiple function names. However, usually when we write a plugin, we try to use only one name to contain all of its contents. Our example plug-in is named "Highlight"
JavaScript code
function() { // Our plugin implementation code goes here. }; 我们的插件通过这样被调用: $(‘#myDiv‘).hilight();
But what if we need to decompose our implementation code into multiple functions? There are a number of reasons: design needs, easier or more readable implementations, and more in line with object-oriented. This is a real hassle, breaking down the functionality into multiple functions without adding extra namespaces. For the sake of recognizing and using functions as the most basic class object in JavaScript, we can do this. Just like any other object, a function can be specified as a property. So we have declared that "hilight" is a Property object of jquery, and any other property or function that we need to expose can be declared in the "hilight" function. Continue later.
2.2 Accept the options parameter to control plug-in behavior
Let's add features to our plug-in to specify the foreground and background colors. We might let the option pass to the plug-in function like an options object. For example:
JavaScript code
// plugin definition $.fn.hilight = function(options) { var defaults = { foreground: ‘red‘, background: ‘yellow‘ }; // Extend our default options with those provided. var opts = $.extend(defaults, options); // Our plugin implementation code goes here. }; 我们的插件可以这样被调用: $(‘#myDiv‘).hilight({ foreground: ‘blue‘ });
2.3 Exposing the default settings for plugins
One of the improvements we should take with the above code is to expose the plugin's default settings. This makes it easier for plug-in users to overwrite and modify plugins with less code. Next we start using the function object.
JavaScript code
Plugin definition $.fn.hilight =function//Extend Our default options with those provided. //Note that the first arg to extend are an empty object-// To keep from overriding our "Defaults" object. var opts = $.extend ({}, $.fn.hilight.defaults, options); //our plugin implementation code goes here.}; //plugin defaults-added as a property in our plugin function $.fn.hilight.defaults = {Foreg Round: ' Red ', background: ' yellow '}; Now the consumer can include a line like this in their script: Span class= "Hljs-comment" >//this only needs to be called once and is not necessarily called in the ready block $.fn.hilight.defaults.foreground = ' #myDiv '). Hilight () ;
As you can see, we allow the user to write a line of code in the plugin's default foreground color. And users still have the option to overwrite these new defaults when they need them:
// 覆盖插件缺省的背景颜色 $.fn.hilight.defaults.foreground = ‘blue‘; // ... // 使用一个新的缺省设置调用插件 $(‘.hilightDiv‘).hilight(); // ... // 通过传递配置参数给插件方法来覆盖缺省设置 $(‘#green‘).hilight({ foreground: ‘green‘ });
2.4 Appropriate exposure to some functions
This section will step-by-step to the previous code by extending your plugin in an interesting way (while letting others expand your plugin). For example, the implementation of our plug-in can define a function called "format" to format the highlighted text. Our plugin now looks like this, and the default format method implementation section is below the Hiligth function.
JavaScript code
Plugin definition $.fn.hilight =function(options) {Iterate and reformat each matched element return this.each (function () {var $ This = $ (this); //... var markup = $this.html (); //call our Format function markup = $.fn.hilight.format (markup); $ this.html (markup);}); }; //define our Format function $.fn.hilight.format = functionreturn ' </strong> ';};
It's easy to support other properties in the options object by allowing a callback function to override the default settings. This is another great way to modify your plugin. The technique shown here is to further effectively expose the format function so that he can be redefined. Through this technique, other people are able to pass their own settings to overwrite your plugin, in other words, so that other people can also write plugins for your plugin.
Considering the useless plugins we've created in this article, you might want to know when it's going to be useful. A real example is the cycle plugin. This cycle plugin is a slide show plugin that he can support many internal transformations to scroll, slide, fade, etc. In practice, however, there is no way to define the effects of each type that might be applied to a sliding change. That's where extensibility is useful. The cycle plugin exposes "transitions" objects to the user, allowing them to add their own transformation definitions. The plugin defines it like this:
// ... };
This technique enables others to define and transfer the transform settings to the cycle plugin.
2.5 Keeping private functions private
This technique exposes a part of your plugin to be overwritten is very powerful. But you need to think carefully about the parts of your implementation that are exposed. Once exposed, you need to keep any changes to the parameters or semantics in your mind that might undermine backwards compatibility. A rationale is that if you are not sure whether you are exposing specific functions, then you may not need to do that.
So how do we define more functions without cluttering up namespaces and not exposing implementations? This is the function of the closure. To demonstrate, we will add another "debug" function to our plugin. This debug function will format the output of the selected element to the Firebug console. In order to create a closure, we will wrap the entire plug-in definition in a function.
JavaScript code
(function ($) {//plugin definition $.fn.hilight = functionthis); //...}; //Private function for debugging function debug ($obj) {if (window.console && Window.console.log) window.console.log ( ' hilight selection Count: ' + $obj. Size ()); }; //...}) (JQuery);
Our "Debug" method cannot be entered from outside closures, so it is private to our implementation.
2.6 Support Metadata Plugin
On the basis of the plugin you are writing, adding support for the metadata plugin will make him more powerful. Personally, I like this metadata plugin because it allows you to use a little "markup" overlay plugin option (this is useful when creating an example). And it's very easy to support it. Update: Comments have a bit of tuning recommendations.
JavaScript code
$.fn.hilight = Function//... //build main options before element iteration var opts = $.extend ({}, $.fn.hilight.defaults, options); return this.each (function () {var $ This = $ (this); //build element specific options var o = $.meta? $.extend ({}, OPTs, $this.data ()): OPTs //...
These changes do something: it's a test of whether the metadata plugin is installed if it is installed, it can expand our options object by extracting the metadata as the last parameter to the Jquery.extend, then it will overwrite any other option settings. Now we can drive the behavior from "markup" if we choose "Markup":
The call can be written like this: Jquery.foo (); or $.foo ();
JavaScript code
<!-- markup --> <div class="hilight { background: ‘red‘, foreground: ‘white‘ } Have a nice day! </div> <div class="hilight { foreground: ‘orange‘ }"> Have a nice day! </div> <div class="hilight { background: ‘green‘ }"> Have a nice day! </div> 现在我们能高亮哪些div仅使用一行脚本: $(‘.hilight‘).hilight();
2.7 Integration
Here's the code to get our example done:
JavaScript code
Create a closure (function($) {Plug-in definition $.fn.hilight =function(options) {Debug (this);Build main options before element iterationvar opts = $.extend ({}, $.fn.hilight.defaults, Options)Iterate and reformat each matched elementReturnThis.each (function() { $This = $ (this);Build element Specific Optionsvar o = $.meta? $.extend ({}, opts, $This.data ()): opts;Update element Styles $This.css ({backgroundcolor:o.background, color:o.foreground});var markup = $This.html ();Call our Format function markup = $.fn.hilight.format (markup); $This.html (markup); }); };Private Function: Debuggingfunction debug ($obj) {if (window.console && Window.console.log) window.console.log ( ' hilight selection Count: ' + $obj. Size ()); }; //definition exposes the Format function $.fn.hilight.format = function (TXT) {return ' <strong> ' + txt + </strong> ";}; //plug-in defaults $.fn.hilight.defaults = {foreground: ' Red ', Background: ' yellow '}; //closing}) (JQuery);
This design has allowed me to create a powerful plug-in that conforms to specifications. I hope it will help you to do the same.
3. Summary
jquery has two methods for developing plug-ins, namely:
jQuery.fn.extend(object); 给jQuery对象添加方法。jQuery.extend(object); 为扩展jQuery类本身.为类添加新的方法。
3.1 JQuery.fn.extend (object);
What's the FN thing? If you look at the jquery code, it's not hard to find.
jQuery.fn = jQuery.prototype = { function( selector, context ) {//.... //...... };
The original Jquery.fn = Jquery.prototype. It's certainly not strange to prototype. Although JavaScript does not have a clear class concept, it is more convenient to use a class to understand it. jquery is a well-encapsulated class, such as we use the statement $ ("#btn1") to generate an instance of the jquery class.
JQuery.fn.extend (object); The extension to Jquery.prototype is to add "member functions" to the jquery class. An instance of the jquery class can use this "member function".
For example, we want to develop a plugin, make a special edit box, when it is clicked, then alert the contents of the current edit box. You can do this:
$.fn.extend({ alertWhileClick:function(){ $(this).click(function(){ alert($(this).val()); }); } });
$ ("#input1"). Alertwhileclick (); On the page: <input id= "INPUT1" type= "text"/>
$ ("#input1") is a jquery instance, and when it calls the Member method Alertwhileclick, it implements the extension, which pops up the contents of the current edit each time it is clicked.
3.2 Jquery.extend (object);
Adding a class method to the jquery class can be understood as adding a static method. Such as:
$.extend({ add:function(a,b){return a+b;} });
Adds a "static method" for jquery to add, which can then be used where jquery is introduced, $.add (3,4); Return 7
jquery Plugin Development Full analysis