After developing a lot of jquery plug-ins, I slowly developed a set of jquery plug-ins to develop a comparative standard structure and patterns. So I can copy & paste most of the code structure, just focus on the most important logic code on the line.
Using the same design pattern and architecture also makes it easier to fix bugs or develop two of times. A validated architecture ensures that my plugins are not a big problem, whether the plugin is simple or complex.
I am here to share 10 lessons I have summed up.
1. Put all your code in the closure
This is the most I have used. But sometimes the method outside the closure cannot be called. However, your plugin code is only for your own plug-in service, so there is no problem, you can put all the code in the closure. And the method should probably be inside the prototype method, as we'll talk about later on.
(Function ($)
{
code here
}) (JQuery);
2. Provide default options for plugins
Your plugin should have some options that are available for developers to set up, so providing a restore default option is necessary. You can set these options by using the Extend feature of jquery:
var defaultsettings = {
Mode: ' Pencil ',
Linewidthmin: ' 0′,
Linewidthmax: ' 10′,
LineWidth: ' 2′
};
Settings = $.extend ({}, DefaultSettings, Settings | | {});
3. Use to return an element
A good feature of javascript/jquery is the ability to cascade methods, so we should not break this feature and always return an element in the method. I follow this rule in every jquery plugin I have.
$.fn.wpaint = function (settings)
{
Return This.each (function ()
{
var Elem = $ (this);
Run some code here
}
}
4. One-time code outside the main loop
This one is important, but it is often overlooked. To put it simply, if you have a piece of code that is a bunch of default values, you just have to instantiate it once, instead of instantiating it every time you call your plug-in function, you should put this code outside the plug-in method. This allows your plug-in to run more efficiently and save memory. We will discuss the prototype later, and see how this method is used in practice.
var defaultsettings = {
Mode: ' Pencil ',
Linewidthmin: ' 0′,
Linewidthmax: ' 10′,
LineWidth: ' 2′
};
$.fn.wpaint = function (settings)
{
Settings = $.extend ({}, DefaultSettings, Settings | | {});
Return This.each (function ()
{
var Elem = $ (this);
Run some code here keleyi.com
}
}
You can notice that the "DefaultSettings" in the code above is completely outside the plugin method, since the code is inside the closure, we don't have to worry about these variables being rewritten.
5. Why to set Class prototyping
As your code of blood and Flesh, methods and functions should be placed within the prototype function. There are two reasons:
It can save a lot of memory because you can create these methods without repeating them.
Referencing an out-of-the-box method to create a new one is much faster.
Simply put, prototype is an extension of an object that provides methods to it without instantiating them in each object. This also makes your code more organized and efficient. Once you get used to this type of development, you'll find that it saves you a lot of time in your future projects.
6. How to set the Class prototyping
There are two parts to setting up a prototype method. First we need to create our original class definition, which in most cases means creating an object. This definition contains a different part of each object instance. In my paint jQuery Plugin plugin, I wrote this:
function Canvas (settings)
{
this.settings = settings;
This.draw = false;
This.canvas = null;
This.ctx = null;
return this;
}
Here's how to add a global approach:
Canvas.prototype =
{
Generate:function ()
{
Generate code
}
}
The key here is to make the prototype method generic, but the data is each instance of its own and can be referenced with "this".
7. Use the "this" object
By using "$this", we can pass the correct reference to another closure. We may also need to pass $this references to other methods. It should be noted that the name of the $this can be changed, arbitrary variable names can be.
Canvas.prototype =
{
Generate:function ()
{
Some code
var $this = this;
var Buton =//...some Code
Button.Click (function () {
Using this is not being found since it has it's own this
Use $this instead.
$this. SomeFunc ($this);
});
},
Somefunc:function ($this)
{
Won ' t know what "this" is.
Use $this instead passed from the Click event
}
}
8. Save the settings in each of the objects
I always save my settings in each object and then manipulate its own settings. So you don't have to pass a lot of arguments in different ways. Putting these variables in the object also makes it easy for you to call these variables elsewhere.
function Canvas (settings)
{
this.settings = settings;
return this;
}
9. Separating your prototype method logic
This may be a basic principle. When you hesitate to provide a way, you can ask yourself, "If someone else wants to rewrite this method, will your code meet his needs?" Or "how difficult is it for someone else to write this method?" Of course, this is a matter of flexibility. Here is a list of my Color picker jQuery Plugin methods, you can refer to:
Generate ()
Appendcolors ()
ColorSelect ()
Colorhoveron ()
Colorhoveroff ()
Appendtoelement ()
Showpalette ()
Hidepalette ()
10. Setter/getter Options available
This one is not necessary, but I found all my plugins are in this one. Because it only requires a little bit of code, it can provide someone with a function that he might need.
Basically, we just have to let the developer set or get the value that the element already exists:
var linewidth = $ ("#container"). Wpaint ("LineWidth");
$ ("#container"). Wpaint ("LineWidth", "5″");
First we want to associate the element with the object, and then we can refer to it. Let's do the following before returning the element:
Return This.each (function ()
{
var Elem = $ (this);
var canvas = new canvas (settings);
Run some code here
Elem.data ("_wpaint_canvas", canvas);
}
The following code clarifies what we are going to do:
$.fn.wpaint = function (option, settings)
{
if (typeof option = = = ' object ')
{
settings = option;
}
else if (typeof option = = = ' String ')
{
If
This.data (' _wpaint_canvas ') &&
Defaultsettings[option]!== undefined
){
var canvas = this.data (' _wpaint_canvas ');
if (settings)
{
Canvas.settings[option] = settings;
return true;
}
Else
{
return canvas.settings[option];
}
}
Else
return false;
}
Return This.each (function ()
{
Run some code here
}
}
The above 10 articles basically cover the core of jquery plug-in development and can be used as a template for development. A set of basic code can greatly shorten your development time, and will allow you to design the plug-in architecture more confident.
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:
Jquery.foo = function () {
Alert (' This is a test. This was only a test. Keleyi.com ');
};
1.2 Adding multiple global functions
Add multiple global functions, which can be defined as follows:
Jquery.foo = function () {
Alert (' This is a test. This was only a test. Collayi ');
};
Jquery.bar = function (param) {
Alert (' This function takes a parameter, which is "' + param + '".);
};
Called when it is the same as a function: Jquery.foo (); Jquery.bar (); or $.foo (); $.bar (' Bar ');
1.3 Using Jquery.extend (object)
Jquery.extend ({
Foo:function () {
Alert (' This is a test. This was 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.
Jquery.myplugin = {
Foo:function () {
Alert (' This is a test. This was only a test. ');
},
Bar:function (param) {
Alert (' This function takes a parameter, which is "' + param + '".);
}
};
The function that takes the namespace is still the global function, the method that is used when calling:
$.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:
(function ($) {
$.fn.extend ({
Pluginname:function (Opt,callback) {
Our plugin implementation code goes here. Collayi
}
})
}) (JQuery);
Form 2:
(function ($) {
$.fn.pluginname = function () {
Our plugin implementation code goes here. Keleyi.com
};
}) (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"
$.fn.hilight = function () {
Our plugin implementation code goes here. Keleyi.com
};
Our plug-in is called by this way:
$ (' #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.
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:
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.
};
Our plug-in can be called this way:
$ (' #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.
Plugin definition
$.fn.hilight = function (options) {
Extend Our default options with those provided.
Note that the first arg to extend are an empty object-
This was 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 on our plugin function
$.fn.hilight.defaults = {
Foreground: ' Red ',
Background: ' Yellow '
};
Now the user can include a line like this in their script:
This only needs to be called once and is not necessarily called in the ready block.
$.fn.hilight.defaults.foreground = ' Blue ';
Next we can use the plug-in method like this, as a result it sets the blue foreground color:
$ (' #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:
Overwrite the default background color of the plugin
$.fn.hilight.defaults.foreground = ' Blue ';
// ...
Call the plugin with a new default setting
$ ('. Hilightdiv '). Hilight ();
// ...
Override default settings by passing configuration parameters to plug-in methods
$ (' #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.
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 = function (TXT) {
Return ' <strong> ' + txt + ' </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:
$.fn.cycle.transitions = {
// ...
};
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.
(function ($) {
Plugin definition
$.fn.hilight = function (options) {
Debug (this);
// ...
};
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.
$.fn.hilight = function (options) {
// ...
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;
//... Keleyi.com
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 ();
<!--Markup--
<div class= "hilight {background: ' Red ', foreground: ' White '}" >
Had a nice day!
</div>
<div class= "Hilight {foreground: ' Orange '}" >
Had a nice day!
</div>
<div class= "hilight {background: ' green '}" >
Had a nice day!
</div>
Now we can highlight which Div uses only one line of script:
$ ('. Hilight '). Hilight ();
2.7 Integration
Here's the code to get our example done:
Create a closed package
(function ($) {
Definition of plug-in
$.fn.hilight = function (options) {
Debug (this);
Build main options before element iteration
var opts = $.extend ({}, $.fn.hilight.defaults, options);
Iterate and reformat each matched element
Return This.each (function () {
$this = $ (this);
Build element Specific Options
var 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: Debugging
function Debug ($obj) {
if (window.console && window.console.log)
Window.console.log (' Hilight selection count: ' + $obj. Size ());
};
Define the exposure Format function
$.fn.hilight.format = function (TXT) {
Return ' <strong> ' + txt + ' </strong> ';
};
Plug-in defaults
$.fn.hilight.defaults = {
Foreground: ' Red ',
Background: ' Yellow '
};
Closing closure
}) (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); Adds a method to a jquery object.
Jquery.extend (object); To extend the jquery class itself. Adds a new method to the class.
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 = {
Init:function (Selector, context) {//....
... keleyi.com
};
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
JQ Plugin Development