JQuery plugin development and jquery plugin
Original article address: jQuery plug-in development
I have also made a little research on jQuery plug-in development. I have also written many plug-ins and shared a course on plug-ins with my team. At the beginning, I realized that the code was very complex. Now I can see it clearly again. Here I will share my summary to help those who have encountered the same problems as me.
What do I do
What I wantJavascript plugin
There should be the following features:
* The following Code assumes that jQuery exists.
First form of plug-ins
In this case, we usually definefunction
.
function pluginName($selector){ $.each($selector, function () { $(this).css("background-color", "#ccc"); // to do something... });}// pluginName(document.getElementsByClassName("demo"));
Because I am talking about jQuery plug-in development, I now extend this code to jQuery. The Code is as follows:
// IIFE (call the function expression immediately); [Refer to http://suqing.iteye.com/blog/1981591/#; (function ($) {// extend this method to jQuery. // $. extend () is that the method is extended to $ object, and $. fn. extend is different. Extend to $. fn. after xxx, // $ (selector) can be called ). xxx () $. fn. extend ({// plug-in name pluginName: function () {// traverses the set of matching elements // note that there is a "return" to return the processed object, implement chained operation return this. each (function () {// write the corresponding code here for processing}) ;}}); // transmits jQuery to the inner scope. If window, if you use many documents, you can also upload them here. //}) (jQuery, window, document, undefined) ;}( jQuery, undefined); // call method $ (". selector "). pluginName (). otherMethod ();
However, it is far from enough. Currently, only two problems have been solved.
Second form of plug-ins
Now, add parameter support to the plug-in. The Code is as follows:
; (Function ($) {$. fn. pluginName = function (options) {// merge parameters. Use "extend" to merge default parameters and custom parameters var args = $. extend ({}, $. fn. pluginName. defaults, options); return this. each (function () {console. log (args. text); // to do something ...});}; // default parameter $. fn. pluginName. defaults = {text: "hello" };}) (jQuery); // $ (". selector "). pluginName ({// text: "hello world! "//});
It is easier to add parameters and solve another problem.
Third form of plug-ins
Now let's add method support, as I mentioned earlierControllable LifecycleFor example, addreInit
,destory
To control the plug-in.
; (Function ($) {$. fn. pluginName = function (method) {// if the first parameter is a string, find whether the method exists and call it. If the parameter is an object, call the init method ;. if (methods [method]) {// if this method exists, call this method // apply. the process of converting method (arg1, arg2, arg3) to method (obj, [arg1, arg2, arg3. // Array. prototype. slice. call (arguments, 1) is to convert the parameters of the method into an array. return methods [method]. apply (this, Array. prototype. slice. call (arguments, 1);} else if (typeof method =' Object' |! Method) {// If the input parameter is "{...} ", it is considered as an initialization operation. return methods. init. apply (this, arguments);} else {$. error ('method' + Method + 'does not exist on jQuery. pluginName ') ;}}; // do not extend the method to $. fn. on pluginName. built-in "methods" in the closure to save the method, similar to the common method. var methods = {/*** Initialization Method * @ param _ options * @ return {*} */init: function (_ options) {return this. each (function () {var $ this = $ (this); var args = $. extend ({}, $. fn. pluginName. defaults, _ options );//...})}, publicMethod: function () {private_methods.demoMethod () ;}}; // Private method function private_methods ={ demoMethod: function () {}} // default parameter $. fn. pluginName. defaults = {};}) (jQuery); // call method // $ ("div "). pluginName ({...}); // initialization // $ ("div "). pluginName ("publicMethod"); // CALL THE METHOD
Solve another problem
Fourth form of plug-ins
The third form of plug-in modification can already meet the needs of most plug-ins. Keep improving. Continue to upgrade.
The fourth form of plug-in isSitu zhengmei
OfJavascript Framework Design
. Added point Object-Oriented Knowledge.
(Function ($) {var Plugin = function (element, options) {this. element = element; this. options = options;}; Plugin. prototype = {create: function () {console. log (this. element); console. log (this. options) ;}}; $. fn. pluginName = function (options) {// merge the parameter return this. each (function () {// write the corresponding code here to process var ui =$. _ data (this, "pluginName"); // If the element has not been initialized (it may be a newly added element), initialize it. if (! Ui) {var opts = $. extend (true, {}, $. fn. pluginName. defaults, typeof options = "object "? Options :{}); ui = new Plugin (this, opts); // cache plug-in $. _ data (this, "pluginName", ui);} // call the method if (typeof options = "string" & typeof ui [options] = "function ") {// method ui [options] for executing the plug-in. apply (ui, args) ;}};}; $. fn. pluginName. defaults = {};}) (jQuery); // The call method is the same as before.
Here we need to mention caching this thing. Many plug-ins are used, and this is really a good thing.
In the development of traditional object-oriented plug-ins, at least one variable will be declared to save it, but I have not written jQuery plug-ins yet, which is very troublesome to use. It is much easier to cache the initialized plug-in. Code$("#target").data("pluginName")
You can get the object. Let's see if there are any problems that haven't been solved.
Fifth Form of plug-ins
Check whether the above Code is a bit dizzy. If yes, take a short rest and come back later, the following code is more exciting. The last solution is comprehensive. Solution fromBootstrap
The following code uses the Bootstrap button plug-in as an example.
! Function ($) {// ecma262v5 is a new feature that requires rigorous coding. "use strict "; // button public class definition // ================================ var Button = function (element, options) {this. $ element = $ (element); this. options = $. extend ({}, Button. DEFAULTS, options) ;}; Button. DEFAULTS = {loadingText: 'loading... '}; Button. prototype. setState = function (state ){//...}; button. prototype. toggle = function () {//...}; // Button plugin definition // =========================var old =old. fn. button; // $. fn. the button may have been a previously defined plug-in, so there is no conflict processing here. $. Fn. button = function (option) {return this. each (function () {var $ this = $ (this); // determine whether the initialization is performed based on var data = $ this. data ('bs. button '); var options = typeof option = 'object' & option; // if it has not been initialized, initialize it if (! Data) $ this. data ('bs. button ', (data = new Button (this, options); if (option = 'toggle') data. toggle (); else if (option) data. setState (option)}; // ① exposes the class name, which can be used to customize extensions for the plug-in $. fn. button. constructor = Button; // extended mode // set: $. fn. button. constructor. newMethod = function () {}// usage: $ btn. button ("newMethod"); // ② No conflict processing $. fn. button. noConflict = function () {$. fn. button = old; return this}; // ③ Event proxy, smart initialization $ (document ). on ('click. bs. button. data-api ',' [data-toggle ^ = button] ', function (e) {var $ btn = values (e.tar get); // find the object to be initialized if (! $ Btn. hasClass ('btn ') $ btn = $ btn. closest ('. btn '); // call the method directly. If the method is not initialized, $ btn is initialized internally. button ('toggle '); e. preventDefault () ;}) ;}( jQuery );
Let's see if there are any problems that haven't been solved.
Supplement
The current plug-ins require high flexibility. For example, you want the plug-ins to be compatible with each other at the same time.jQuery
AndZepto
Or the AMD or CMD specifications must be supported.
- Support for jQuery and Zepto
if (window.jQuery || window.Zepto) { (function ($) { // plugin code... })(window.jQuery || window.Zepto);}
- Middleware support, node
if (typeof(module) !== 'undefined'){ module.exports = pluginName;}
- Requirejs (AMD) support
if (typeof define === 'function' && define.amd) { define([], function () { 'use strict'; return pluginName; });}
- Seajs (CMD) support
if (typeof define === 'function') { define([], function () { 'use strict'; return pluginName; });}
Call ~, The problem has been solved. If you have any questions about the code, you can check it out. It doesn't matter if you don't understand the following. In actual development, the first few are enough. It should be emphasized that the more advanced the writing method, the better it should be, the more appropriate the needs of your project should be.
Of course, there are more and better plug-in development methods that need to be discovered by everyone.