Read Catalogue
- Basic methods
- Supports chained calls
- Let the plug-in receive parameters
- Object-oriented plug-in development
- About namespaces
- About variable definition and naming
- Advantages of compression
- Tools
- GitHub Service Hooks
Original: http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html
The most successful part of jquery, I think, is that its extensibility has attracted many developers to develop plug-ins to build an ecosystem. This is like the big companies competing to do the platform, the platform to the world. Apple, Microsoft, Google and other giants, all have their own platform and ecological circle.
Learning to use jquery is not difficult, because it's easy to learn, and I'm sure you'll be using or familiar with many of its plugins after you touch jquery. If you want to increase your ability to a step, it's a good idea to write a plugin of your own.
This tutorial may not be the most elaborate, but it must be the most meticulous.
jquery Plugin Development model
Software development process is the need for certain design patterns to guide development, with the model, we can better organize our code, and from these predecessors summed up the model learned a lot of good practice.
According to the description of jquery advanced programming, there are three main ways to develop jquery plugins:
- Extend jquery with $.extend ()
- Add a new method to jquery through $.fn
- Created using the part factory method of the jquery UI by $.widget ()
Usually we use the second method for simple plug-in development, saying that simplicity is relative to the third way. The third way is to develop more advanced jquery parts, the model developed by the parts with a lot of jquery built-in features, such as plug-in state information automatically saved, a variety of plug-ins commonly used methods, very intimate, here is not elaborate.
The first approach is too simple to add a static method to the jquery namespace or to the idea of jquery. So we call through the $.extend () Add function directly through the $ symbol call ($.myfunction ()) without having to check the DOM element ($ (' #example '). MyFunction ()). Take a look at the example below.
$.extend ({ sayhello:function (name) { Console.log (' Hello, ' + (name? Name: ' Dude ') + '! '); }) $.sayhello (); Call $.sayhello (' wayou '); Call with parameter
Operation Result:
In the above code, a SayHello function is added to jquery via $.extend () and then called directly via $. Here you can think that we have completed a simple jquery plugin.
But as you can see, it is convenient to define some auxiliary methods in this way. A custom console, for example, outputs information in a specific format that can be called once in a program by jquery wherever it is needed.
$.extend ({ log:function (message) { var now = new Date (), y = now.getfullyear (), m = now.getmonth () + 1,/ /! The month in JavaScript is 0-based d = now.getdate (), h = now.gethours (), min = Now.getminutes (), s = now.getseconds ( ), Time = y + '/' + M + '/' + D + ' + H + ': ' + min + ': ' + S; Console.log (Time + ' My App: ' + message); }}) $.log (' initializing ... '); Call
But this approach does not take advantage of the convenience of jquery's powerful selectors, the need to work with DOM elements and to better apply the plug-in to selected elements, or to use the second development approach. Most of the plugins you see or use are developed in this way.
Plug-in development
Let's look at the second way of jquery plugin development.
Back to the top of the basic method
First look at its basic format:
$.fn.pluginname = function () { //your code goes here}
Basically is to $.fn above add a method, name is our plug-in name. Then our plug-in code expands in this method.
For example, if we turn all the link colors on the page to red, we can write the plugin as follows:
$.fn.myplugin = function () { //In this case, this refers to the element selected with jquery //example: $ (' a '), then this=$ (' a ') this.css (' Color ', ' Red ');}
Within this function of the plug-in name definition, this refers to the element that we select with the jquery selector when invoking the plugin, which is generally a collection of jquery types. For example, $ (' a ') returns a collection of all the A tags on the page, and the collection is already a jquery wrapper type, which means that you can invoke other methods of jquery directly when you manipulate it without having to wrap it with a dollar sign.
So in the plugin code above, we invoke the jquery CSS () method on this, which is equivalent to calling $ (' a '). css ().
It is important to understand the meaning of this in this place. So that you know why you can directly commercial jquery methods at the same time in other places this is not the same time we need to re-packaging with jquery to invoke, as described below. Beginner is easy to be dizzy by the value of this, but it is not difficult to understand.
Now you can go to the page to try our code, put a few links on the page, call the plugin after the link font into red.
<ul> <li> <a href= "Http://www.webo.com/liuwayong" > My Weibo </a> </li> <li> <a href= "http://http://www.cnblogs.com/Wayou/" > My blog </a> </li> <li > <a href= "http://wayouliu.duapp.com/" > My station </a> </li></ul><p> This is P tag is not a label, I will not be affected </p><script src= "jquery-1.11.0.min.js" ></script><script src= " Jquery.myplugin.js "></script><script type=" Text/javascript "> $ (function () { $ (' a '). Myplugin (); }) </script>
Operation Result:
Further, each specific element is processed in the plug-in code instead of a collection, so that we can operate on each element accordingly.
We already know that this refers to the collection returned by the jquery selector, so each element of the collection can be processed by invoking the. each () method of jquery, but it is important to note that within each method, this refers to the normal DOM element. If you need to call jquery's method then you need to re-wrap it with $.
For example, now we want to show the real address of the link in each link, first through each of the a tags, and then get the value of the HREF attribute and add to the link text behind.
After the change our plug-in code is:
$.fn.myplugin = function () { //In this case, this refers to the element this.css selected with jquery (' Color ', ' red '); This.each (function () { //action per element $ (this). Append ("+ $ (This). attr (' href '))}) }
The calling code is still the same, we call this plugin by selecting all the a tags on the page
Operation Result:
In this, you can already write a simple jquery plugin. It's not that hard.
The following starts the jquery plugin to write an important part of the parameter reception.
Back to top support chaining calls
We all know that jquery. A often elegant feature is the ability to support chained calls, and the choice of DOM elements can be repeated to call other methods.
To make the plug-in not break the chain call, just return it.
$.fn.myplugin = function () { //In this case, this refers to the element this.css selected with jquery (' Color ', ' red '); Return This.each (function () { //action for each element $ (this). Append ("+ $ (This). attr (' href '))}) }
Back to the top let the plug-in receive parameters
A strong plug-in can be customized to the user, which requires us to provide the plug-in should be considered comprehensive, as far as possible to provide the appropriate parameters.
For example, now we do not want to make the link only red, we let the user of the plugin to define what color to display, it is very convenient to do this, only need to pass the user when the call to a parameter. At the same time we receive in the plugin code. On the other hand, in order to be flexible, the user can not pass parameters, the plug-in will give the default value of the parameter.
The Extend method of jquery is usually used to handle the reception of plug-in parameters, as mentioned above, but that is the case of passing a single object to the Extend method, which is merged into jquery, so we can invoke the methods contained in the new merge object on jquery, Like the example above. When you pass more than one argument to the Extend method, it merges all the parameter objects into the first one. At the same time, if the object has the same name attribute, then the merge will overwrite the previous one.
With this, we can define an object in the plug-in that holds the default value of the plug-in parameter, merges the received parameter object onto the default object, and finally implements the user-specified value parameter using the specified value, using the plug-in default value for unspecified parameters.
For illustrative purposes, specify a parameter fontsize, which allows the font size to be set when the plugin is called.
$.fn.myplugin = function (options) { var defaults = { ' color ': ' Red ', ' fontSize ': ' 12px ' }; var settings = $.extend (defaults, options); Return this.css ({ ' color ': Settings.color, ' fontSize ': Settings.fontsize });}
Now, we call the time to specify the color, the font size is not specified, will be used in the plug-in default value of 12px.
$ (' a '). Myplugin ({ ' color ': ' #2C9929 '});
Operation Result:
Specify both color and font size:
$ (' a '). Myplugin ({ ' color ': ' #2C9929 ', ' fontSize ': ' 20px '});
Protect the default parameters.
Notice that the above code will change the value of the defaults when it calls extend, which is not good, because some things should be maintained as plug-ins, and if you want to use these defaults in subsequent code, it has been changed by the user's incoming parameters when you visit it again.
A good practice is to use a new empty object as the first parameter of $.extend, and defaults and user-passed parameter objects are immediately followed, so the benefit is that all values are merged into the empty object, protecting the default values inside the plug-in.
$.fn.myplugin = function (options) { var defaults = { ' color ': ' Red ', ' fontSize ': ' 12px ' }; var settings = $.extend ({},defaults, options);//Make an empty object The first argument return this.css ({ ' color ': Settings.color, ' fontSize ': Settings.fontsize });}
In this, the plug-in can receive and process parameters, you can write out more robust and flexible plug-ins. To write a complex plug-in, the amount of code will be very large, how to organize the code is a need to face the problem, there is no good way to organize the code, the overall feeling will be disorganized, but also not good maintenance, so the plug-in all the method properties wrapped to an object, with object-oriented thinking to develop, Will undoubtedly make the work much easier.
Back to top object-oriented plug-in development
Why object-oriented thinking, because if not, you might need a way to define a function, and when you need another method, you can define a function, and similarly, when you need a variable, define some variables that are scattered throughout the code without a rule.
Still old problem, inconvenient maintenance, also not clear. Of course, these problems are not reflected when the code is small.
If you define the necessary variables to the object's properties, the function becomes the method of the object, when we need to get through the object, one is convenient to manage, and the other does not affect the external namespace, because all of these variable names and method names are inside the object.
Then the above example, we can abstract this plugin into a beautification of the Page object, because his function is to set the color Ah font ah what, of course, we can also add other features such as setting the underline ah what. Of course, the abstract object of this example is a bit of a fuss, just for demonstration purposes. Later I might introduce a jquery plugin I wrote sliphover, where the code is more, and this pattern is used.
So we create a new object named Beautifier, and then we use this object in the plugin to encode it.
Define Beautifier constructor var beautifier = function (Ele, opt) {this . $element = ele, this.defaults = { ' color ': ' Red ', ' fontSize ': ' 12px ', ' textdecoration ': ' None ' }, this.options = $.extend ({}, this.defaults, opt }//defines Beautifier method beautifier.prototype = { beautify:function () {return this . $element. css ({ ' color ': This.options.color, ' fontSize ': this.options.fontSize, ' textdecoration ': this.options.textDecoration }); }} Use the Beautifier object in the plug-in $.fn.myplugin = function (options) { //create Beautifier entity var beautifier = new Beautifier ( this, options); Call its method return beautifier.beautify ();}
Through the above transformation, our code becomes more object-oriented, but also better maintenance and understanding, in the future to add new features and new methods, only the object can be added to the new variables and methods, and then after the instantiation of the plugin can invoke the newly added things.
Plug-in calls are the same, our changes to the code do not affect the rest of the plugin, but the organization of the Code to change the structure.
$ (function () { $ (' a '). Myplugin ({ ' color ': ' #2C9929 ', ' fontSize ': ' 20px ' })
Specifies that the text is underlined (the new feature we added in the Beautifier object, which is not underlined by default, as in the example above):
$ (function () { $ (' a '). Myplugin ({ ' color ': ' #2C9929 ', ' fontSize ': ' 20px ', ' textdecoration ': ' (Underline ' });})
Here, you can better write complex plugins and organize your code well. When we look back at the code above, there is still room for improvement. Here are some miscellaneous things about namespaces and variables.
Back to top about namespaces
Not only the development of jquery plugins, we should be aware of when writing any JS code is not to pollute the global namespace. Because with the increase of your code, if you intentionally or unintentionally in the global scope to define some variables, it is difficult to maintain, but also easy to write with someone else code conflicts.
For example, you add a variable status to the Global window object in your code, the page references another library that someone else wrote, and you add a variable of the same name to the global, and the final result is definitely not what you want. So, in general, we don't define variables as global, unless we have to.
A good practice is to always wrap your code with self-invoking anonymous functions, so you can be completely assured that it will be used anywhere, with absolutely no conflict.
Wrap your code with self-invoking anonymous functions
We know that JavaScript cannot easily create scopes with curly braces, but functions can form a scope in which code within a domain cannot be accessed by outsiders. If we put our own code in a function, it doesn't pollute the global namespace, and it doesn't conflict with other code.
As above we define a beautifier global variable, it will be attached to the global Window object, in order to prevent this kind of thing, you might say, put all the code in the jquery plug-in definition code inside, that is, put into the $.fn.myplugin inside. This is also a choice. But the code that we actually have about the plugin definition becomes bloated, and in $.fn.myplugin we should actually be more focused on plug-in calls and how we interact with jquery.
So keep the original code intact, and we'll wrap all the code with self-invoking anonymous functions.
(function () { ///define Beautifier's constructor var beautifier = function (Ele, opt) {this . $element = Ele, This.defaults = { ' color ': ' Red ', ' fontSize ': ' 12px ', ' textdecoration ': ' None ' }, this.options = $.extend ({}, this.defaults, opt) } //method for defining Beautifier Beautifier.prototype = { beautify:function () { return this. $element. css ({ ' color ': This.options.color, ' fontSize ': this.options.fontSize, ' textdecoration ': This.options.textDecoration }); } } Using the Beautifier object in the plug-in $.fn.myplugin = function (options) { //create Beautifier entity var beautifier = new Beautifier (this, options); Call its method return beautifier.beautify (); }}) ();
The benefits of doing so are as described above. Another benefit is that the code from the call to the anonymous function will be executed in the first time, and after the page is ready, the code above will be ready to use the plug-in in the later code.
So far it seems to be close to perfection. If we consider other factors, such as we put this piece of code on the page, the previous code did not end with a semicolon, or the previous code to the window, undefined and other such system variables or keywords modified, just as we have in our own code to use, The result is unpredictable, and that's not what we want. I know you have not quite understood, the following detailed introduction.
Passing system variables to the inside of the plug-in as variables
Take a look at the code below, and guess what happens to him?
var foo=function () { ///Someone else's code}//note there's no ending with a semicolon//start our code ... (function () { //Our code: alert (' hello! ');}) ();
Originally other people's Code also works, but the last definition of the function does not end with a semicolon, and then when the page introduced our plug-in, the error, our code does not execute properly.
The reason is that the first pair of parentheses we use to act as a self-invoking anonymous function is connected to a function defined by others above, because there is no semicolon, in short, our code does not parse properly, so error.
So the good thing is that we add a semicolon at the beginning of the code, which is a good habit at all times.
var foo=function () { ///Someone else's code}//note there's no ending with a semicolon//start our code ... ;(function () { //Our code: alert (' hello! ');}) ();
At the same time, it is a good practice to pass system variables in the form of parameters to the inside of the plug-in.
When we do this, system variables such as window have a local reference within the plug-in, which improves access speed and provides some performance improvements.
Finally we get a very safe and well-structured code:
;(function ($,window,document,undefined) { //Our code: //blah blah blah ...}) (jquery,window,document);
And as for this undefined, a little bit more interesting, in order to get unmodified undefined, we did not pass this parameter, but received it when received, because the actual is not transmitted, so ' undefined ' that position received is the real ' Undefined ' out. is not a bit hack taste, it is worth to understand the technology, of course, not I invented, are from the experience of previous learning.
So in the end our plugin became this:
;(function ($, window, document,undefined) { //define Beautifier's constructor var beautifier = function (Ele, opt) {this . $element = Ele, this.defaults = { ' color ': ' Red ', ' fontSize ': ' 12px ', ' textdecoration ': ' None ' } , this.options = $.extend ({}, this.defaults, opt) } //method for defining Beautifier Beautifier.prototype = { beautify:function () { return this. $element. css ({ ' color ': This.options.color, ' fontSize ': This.options.fontSize, ' textdecoration ': This.options.textDecoration }); } } Using the Beautifier object in the plug-in $.fn.myplugin = function (options) { //create Beautifier entity var beautifier = new Beautifier (this, options); Call its method return beautifier.beautify (); }}) (JQuery, window, document);
A secure, well-structured, organized plug-in was written.
Back to top about variable definition and naming
Now talk about variables and methods such as naming, there is no hard rules, but in order to standardize, to follow some of the agreement is very necessary.
variable definition : A good practice is to define the variable name that will be used in the beginning of the code with a var keyword, separating the variable names with commas. There are two reasons:
- One is easy to understand, know the following code will use which variables, while the code appears neat and regular, but also easy to manage, variable definition and logic code separate;
- Second, because all the variables and function names in JavaScript are automatically promoted, also known as the hoist feature of JavaScript, even if you add the definition of a variable to the logic code, the declaration of these variables is promoted to the top of the current scope during the code parsing run. So we define a variable at the beginning of a scope as a more logical approach. Again, of course, it's just a convention, not a requirement.
variable and function naming generally uses the Hump naming method (CamelCase), which is the first letter of the first word in lowercase, followed by the first letter of the word, such as resultarray,requestanimationframe. For constants, all letters are capitalized, and multiple words are separated by underscores, such as width=100,brush_color= ' #00ff00 '. When a variable is a jquery type, it is recommended to start with $, but it is often very convenient to use it, because it is easy to distinguish it from ordinary variables, and we know that it is a jquery type that can invoke jquery-related methods directly on its body as soon as you see it in $. such as Var $element =$ (' a '); It can then be easily used in later code and easily distinguishable from other variables.
use of quotation marks : Since all this is irrelevant to the plugin theme, here are a few more words, the general HTML code inside the use of double quotes, and in JavaScript more than single quotes, such as the following code:
var name = ' Wayou ';d ocument.getelementbyid (' example '). InnerHTML = ' < a href= ' http://wayouliu.duapp.com/' > ' +name + ' </a> '; Href= ".." Keep double quotes in HTML, keep single quotes in JavaScript
On the one hand, the HTML code is originally used in double quotation marks, on the other hand, in JavaScript in quotation marks also need to quote the time, it is required that we single double quotes spaced write is a legitimate statement, unless you use the signifier that is also possible. Furthermore, adhering to such a unification can keep the code style consistent, and will not appear here the string is wrapped in double quotation marks, and the other place is in single quotes.
Code obfuscation and compression
To finish the above steps, has become small. Perhaps you have noticed very early, you download the plug-in, generally will provide a compressed version of the file name usually take a ' min ' word. That is to say minified, compress the condensed version. And usually we use the jquery is also available on the official website compressed version, Jquery.min.js.
Compression here does not refer to the function of the code compression, but by the code inside the variable name, method function name and so on with a shorter name to replace, and delete the comments (if any) to delete the space between the code and the resulting condensed version of the line. At the same time, because the various names in the code have been replaced, others can not read and distinguish their logic, but also play a role in confusing the code.
Back to top of the compression benefits
- After the source code is confused and compressed, the volume is greatly reduced, which makes it lightweight, and speeds up the download speed, both sides of the load become faster. For example, the normal jquery v1.11.0 source code is 276KB, and the compressed version only 94.1kb! The volume is reduced by more than half. This reduction in volume is not negligible for file download speeds.
- After the compression is confusing, can the code still read? Of course not, so incidentally also played the role of code protection. Of course only for you to write some cool code and do not want others to copy the situation. For the jquery community, this is itself an open source world, and JavaScript is not really a real way to prevent others from viewing your code, after all, there is confusion there is anti-obfuscation tool, where the code compression more or the above mentioned compressed file role, At the same time to some extent to prevent others to copy.
Back to top tool
The tools you use are the closure Compiler that Google developed. The tool requires support from the Java environment, so you may need to install the JRE on the machine before using it for closure.
At the same time there are very friends online Code obfuscation compression tool, it is also very convenient to use. All of these tools are a handful of searches.
Plugin Publishing
This step is not necessary, but in the spirit of doing things in a holistic manner, at the same time you may want more people to see or use your plugin.
- First you need to put the plugin code on GitHub to create a service Hook, so that after you update the plugin later, jquery can automatically get the new version of the information and display it on the Plugin center page. For information on how to pass the code to github, you can download the client tools provided by GitHub and you will know how to do it, very handy. About creating a service Hook on GitHub, it's just a matter of a few clicks. This is described below.
- Then you need to make a JSON-formatted manifest file, which includes basic information about the plugin, the format and parameters can be learned in the jquery website Plugin Publishing Guide page, here is a sample file, I wrote a jquery plugin sliphover:
{"Name": "Sliphover", "title": "Sliphover", "description": "Apply direction aware 2d/3d hover effect to images" , "keywords": ["Direction-aware", "animation", "effect", "hover", "image", " Overlay "," gallery "]," version ":" 1.1.1 "," author ": {" name ":" Wayou "," email ":" [Email&nbs P;protected] "," url ":" Https://github.com/Wayou "}," maintainers ": [{" Name ":" Wayou ", "Email": "[email protected]", "url": "Https://github.com/Wayou"}], "Licenses": [ {"type": "MIT", "url": "Https://github.com/jquery/jquery-color/blob/2.1.2/MIT-LICENSE.txt" }], "Bugs": "Https://github.com/Wayou/sliphover/issues", "homepage": "http://wayou.github.io/SlipHover/", "Docs": "http://wayou.github.io/SlipHover/", "Demo": "http://wayou.github.io/SlipHover/", "Download": "https:// Github.com/wayou/sliphover/zipBall/master "," dependencies ": {" jquery ":" >=1.5 "}}
- You can then execute the existing git code in the plugin's root directory to publish the plugin. Where 0.1.0 is the version number, each time your plugin has a new version of the release only need to update the above command version, create a new tag, so that the jquery plug-in center will automatically get the new version information
$ git tag 0.1.0$ git push Origin--tags
Back to the top GitHub Service Hook
1 Click Settings on the right menu of the project
2 Click on ' Webhooks & Services ' after entering the Setup page.
3 then click on the ' Configure Services ' button on the right home page
4 A very long list appears, down to jquery Plugins click
5 Click on the ' Update Settings ' button after clicking on the check box.
The setup is complete here.
Reference:
- jquery Website Learning Center article on plugin development: http://learn.jquery.com/plugins/
- jquery Website Plugin Center: http://plugins.jquery.com/
- jquery Official Plugin release guide: http://plugins.jquery.com/docs/publish/
- JavaScript hoist:http://www.adequatelygood.com/javascript-scoping-and-hoisting.html
- Google Web Developer tool:https://developers.google.com/closure/
Category: Web Front end
jquery writing plugins (GO)