JQuery plug-in development excellent tutorial (let your jQuery go further), jquery excellent

Source: Internet
Author: User
Tags beautifier

JQuery plug-in development excellent tutorial (let your jQuery go further), jquery excellent

Liu woyong's blog is about jQuery's most successful part. I think its scalability attracts many developers to develop plug-ins for it, thus establishing an ecosystem. This is like a big company competing to be a platform. Apple, Microsoft, Google, and other giants all have their own platforms and ecosystems.

Learning to use jQuery is not difficult, because it is easy to learn, and I believe that you will certainly use or be familiar with many of its plug-ins after getting started with jQuery. Writing a plug-in is a good choice if you want to increase your capabilities.

This tutorial may not be the best, but it must be the most meticulous.

JQuery plug-in Development Mode

In the software development process, a certain design pattern is required to guide the development. With the pattern, we can better organize our code, we also learned a lot of good practices from the models summarized by our predecessors.

According to the description of jQuery advanced programming, there are three main jQuery plug-in development methods:

Use $. extend () to extend jQuery
Add a new method to jQuery through $. fn
Use $. widget () to apply jQuery UI's component factory method to create
We usually use the second method for Simple plug-in development, which is relative to the third method. The third method is used to develop more advanced jQuery components. The components developed in this mode have many built-in jQuery features, such as the automatic saving of the status information of the plug-in, A variety of frequently used plug-ins are very considerate. I will not elaborate on them here.

The first method is too simple. It only adds a static method to the jQuery namespace or understood as jQuery. So we call $. the extend () function is directly called using the $ symbol ($. myfunction () without selecting the DOM element ($ ('# example '). myfunction ()). See the following example.

$. Extend ({sayHello: function (name) {console. log ('hello, '+ (name? Name: 'dude') + '! ') ;}}) $. SayHello (); // call $. sayHello ('wayou'); // call with Parameters

Running result:

In the code above, a sayHello function is added to jQuery through $. extend () and then called directly through $. Now you can think that we have completed a simple jQuery plug-in.

As you can see, this method is convenient to define some auxiliary methods. For example, a custom console outputs information in a specific format. Once defined, jQuery can call it wherever necessary in the program.

 

$. Extend ({log: function (message) {var now = new Date (), y = now. getFullYear (), m = now. getMonth () + 1 ,//! In JavaScript, the monthly value starts from 0. 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

 

However, this method cannot take advantage of jQuery's powerful selector. To process DOM elements and apply the plug-in to the selected elements, you still need to use the second development method. Most of the plug-ins you see or use are developed in this way.

Plug-in development

Next we will look at the second method of jQuery plug-in development.

Basic Method

Let's take a look at its basic format:

$.fn.pluginName = function() {  //your code goes here}

Basically, you can add a method to $. fn. The name is our plug-in name. Then our plug-in code is expanded in this method.

For example, if we convert the color of all links on the page to red, we can write this plug-in as follows:

$. Fn. myPlugin = function () {// here, this refers to the element selected by jQuery // example: $ ('A '), then this = $ ('A') this.css ('color', 'red ');}

Within the function defined by the plug-in name, this refers to the elements selected by the jQuery selector when we call the plug-in. this is generally a set of jQuery types. For example, $ ('A') returns the set of all a tags on the page, and the set is already of the jQuery packaging type, that is, when you operate on it, you can directly call other jQuery methods without using the dollar symbol to wrap it.

Therefore, in the above plug-in code, we call jQuery's css () method on this, which is equivalent to calling 'a'{.css ().

It is important to understand the meaning of this in this place. In this way, you can understand why the jQuery method can be commercially used. In other places, this is called only when jQuery is repackaged. Beginners are easily confused by the value of this, but it is not difficult to understand it.

Now we can go to the page and try our code. put several links on the page. after calling the plug-in, the link font turns red.

<Ul> <li> <a href = "http://www.webo.com/liuwayong"> my weibo </a> </li> <a href = "http: // http://www.cnblogs.com/Wayou/ "> my blog </a> </li> <a href =" http://wayouliu.duapp.com/"> my site </a> </li> </ /ul> <p> This is a p tag, not a tag, 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>

Running result:

Next, we will process each specific element in the plug-in code, instead of processing a set, so that we can perform corresponding operations on each element.

We already know that this refers to the set returned by the jQuery selector. the each () method can process every element in the collection, but note that inside the each method, this refers to a common DOM element, if you need to call the jQuery method, you need to use $ to rewrap it.

For example, to display the real address of the link in each link, first traverse all the tags through each, then obtain the value of the href attribute and add it to the link text.

After the change, our plug-in code is:

$. Fn. myPlugin = function () {// here, this refers to this.css ('color', 'red') selected by jQuery; this. each (function () {// operate each element $ (this ). append (''+ $ (this ). attr ('href '));}))}

The call code is the same. We can call this plug-in by selecting all the labels on the page.

Running result:

Now, you can write jQuery plug-ins with simple functions. Is it not that difficult.

The following describes the receipt of parameters in the compilation of jQuery plug-ins.

Support chain call

We all know that jQuery supports chained calling. After DOM elements are selected, other methods can be called continuously.

To prevent the plug-in from breaking this type of chained call, you only need to return it.

$. Fn. myPlugin = function () {// here, this indicates this.css ('color', 'red') selected by jQuery; return this. each (function () {// operate each element $ (this ). append (''+ $ (this ). attr ('href '));}))}

Let the plug-in receive Parameters

A powerful plug-in can be customized by users at will, which requires us to provide comprehensive considerations when writing the plug-in and provide appropriate parameters as much as possible.

For example, if we do not want to make the link red, we allow the plug-in user to define the color of the display. To do this, you only need to input a parameter when calling the plug-in. At the same time, we receive the code in the plug-in. On the other hand, in order to be flexible, users can not pass the parameter, the plug-in will give the default value of the parameter.

Generally, the extend method of jQuery is used to receive the parameters of the processing plug-in. As mentioned above, but when the extend method is passed to a single object, this object will be merged into jQuery, so we can call the methods contained in the new merged object on jQuery, as shown in the above example. When more than one parameter is passed to the extend method, it merges all parameter objects into the first one. At the same time, if an object has an attribute with the same name, the preceding attributes will be overwritten when merged.

With this, we can define an object in the plug-in that saves the default values of the plug-in parameters, and merge the received parameter objects into the default objects, finally, the user-specified parameter uses the specified value. unspecified parameters use the default value of the plug-in.

For ease of demonstration, specify another parameter fontSize, which allows you to set the font size when calling the plug-in.

$.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, when we call this function, we specify the color. If the font size is not specified, the default value of 12px in the plug-in will be used.

$('a').myPlugin({  'color': '#2C9929'});

Running result:

Specify the color and font size at the same time:

$('a').myPlugin({  'color': '#2C9929',  'fontSize': '20px'});

Protect default parameters

Note that the above Code will change the value of ults when calling extend. This is not good because it is used as a plug-in because some of the items should be unchanged, in addition, if you want to use these default values in the subsequent code, When you access it again, the parameter has been changed by the user.

A good practice is to use a new null object as $. the first parameter of extend, defaults and the parameter object passed by the user follow closely. The advantage of doing so is that all values are merged into this empty object, protecting the default values in the plug-in.

$. Fn. myPlugin = function (options) {var defaults = {'color': 'red', 'fontsize': '12px '}; var settings = $. extend ({}, defaults, options); // use an empty object as the first parameter return this.css ({'color': settings. color, 'fontsize': settings. fontSize });}

After receiving and processing parameters, the plug-in can compile a more robust and flexible plug-in. If you want to write a complex plug-in, the amount of code will be very large, and how to organize the code becomes a problem to be faced. Without a good way to organize the code, the overall feeling will be messy, at the same time, it is not easy to maintain. Therefore, packaging all the method attributes of the plug-in to an object and developing it with object-oriented thinking will undoubtedly make the work much easier.

Object-oriented plug-in development

Why do we need an object-oriented thinking? If this is not the case, you may need a method to define a function. When you need another method, define a function at will, similarly, when a variable is needed, variables that are scattered throughout the Code are defined without rules.

It is still an old problem. It is not easy to maintain or clear enough. Of course, these problems cannot be reflected when the code size is small.

If you need to define important variables on the object attributes, the function becomes the object method. when we need them, we can get them through the object to facilitate management. Second, it will not affect the external namespace, because all these variable names and method names are inside the object.

In the above example, we can abstract this plug-in into an object for page beautification, because its function is to set colors, fonts, and so on, of course, we can also add other functions, such as setting underscores. Of course, it is a little difficult to abstract this example into an object. Here it is only used for demonstration. In the future, I may introduce a jQuery plug-in SlipHover compiled by me. There are many codes in it, and this mode can be used.

So we create an object named Beautifier, And then we use this object in the plug-in for encoding.

// Define the Beautifier constructor var Beautifier = function (ele, opt) {this. $ element = ele, this. ults = {'color': 'red', 'fontsize': '12px ', 'textrecoration': 'none'}, this. options = $. extend ({}, this. defaults, opt)} // defines the Beautifier method. prototype = {beauent: function () {return this.w.element.css ({'color': this. options. color, 'fontsize': this. options. fontSize, 'textrecoration': this. options. textDecoration}) ;}}// use the Beautifier object in the plug-in $. fn. myPlugin = function (options) {// create the Beautifier object var beautifier = new Beautifier (this, options); // call its method return beautifier. beautify ();}

Through the above transformation, our code has become more object-oriented and better maintained and understood. To add new functions and methods in the future, you only need to add new variables and methods to the object, after instantiating the plug-in, you can call newly added things.

The call of the plug-in is the same. Our changes to the Code do not affect the plug-in elsewhere, but the code's organizational structure is changed.

$(function() {  $('a').myPlugin({    'color': '#2C9929',    'fontSize': '20px'  });})

 

Specify the underlined text (the new feature in the Beautifier object is not underlined by default, as shown in the preceding example:

$(function() {  $('a').myPlugin({    'color': '#2C9929',    'fontSize': '20px',    'textDecoration': 'underline'  });})

By now, you can better compile complex plug-ins and organize code well. When we look back at the above Code, there is still room for improvement. That is, some miscellaneous information about namespaces and variables.

About namespaces

Not only is the development of jQuery plug-ins, but we should note that the global namespace should not be contaminated when writing any JS Code. As your code grows, it will be difficult to maintain it If you intentionally define some variables in the global scope, and it will easily conflict with the code written by others.

For example, you add a variable status to the global window object in the code to store the status, reference another library written by someone else in the page, and add such a variable with the same name globally, the final result is definitely not what you want. As a result, we generally do not define variables as global variables.

A good practice is to always wrap your code with a self-called anonymous function, so that you can use it securely anywhere without conflict.

Wrap your code with self-called anonymous Functions

We know that JavaScript cannot use curly brackets to easily create scopes, but functions can form a scope, and the code in the domain cannot be accessed by the outside world. If we put our code into a function, it will not pollute the global namespace, and it will not conflict with other code.

As we have defined a Beautifier global variable above, it will be attached to the global window object. to prevent such a thing from happening, you may say, put all the code in the jQuery plug-in definition code, that is, put it in $. fn. myPlugin. This is also an option. But it will make the Code related to the plug-in definition bloated. In $. fn. myPlugin, we should actually focus more on the call of the plug-in and how to interact with jQuery.

So keep the original code unchanged. We wrap all the code with self-called anonymous functions.

(Function () {// defines the Beautifier constructor var Beautifier = function (ele, opt) {this. $ element = ele, this. ults = {'color': 'red', 'fontsize': '12px ', 'textrecoration': 'none'}, this. options = $. extend ({}, this. defaults, opt)} // defines the Beautifier method. prototype = {beauent: function () {return this.w.element.css ({'color': this. options. color, 'fontsize': this. options. fontSize, 'textrecoration': this. options. textDecoration}) ;}}// use the Beautifier object in the plug-in $. fn. myPlugin = function (options) {// create the Beautifier object 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 in the Self-called anonymous function will be executed immediately. After the page is ready, the above Code will prepare the plug-in, to facilitate the use of plug-ins in subsequent code.

So far, it seems almost perfect. If other factors are taken into account, for example, after we put this code on the page, the code written by others in the front will not end with a semicolon, or the previous Code will use the window, undefined and other system variables or keywords have been modified, and we have used them in our own code, so the results are unpredictable. This is not what we want. I know that you are not clear yet. I will introduce it in detail below.

Pass System variables to the plug-in as variables

Let's take a look at the following code. Guess what the result will appear?

Var foo = function () {// others' code} // note that we do not end the code with a semicolon... (Function () {// our code .. Alert ('Hello! ');})();

The Code of others works normally, but the last defined function does not end with a semicolon. When our plug-in is introduced into the page, an error is reported, and our Code cannot be executed normally.

The reason is that the first pair of parentheses used to call the anonymous function is connected to the function defined by others above. Because there is no semicolon in the middle, in short, our Code cannot be parsed normally, so an error is reported.

Therefore, it is a good habit to add a semicolon at the beginning of the Code.

Var foo = function () {// others' code} // note that we do not end the code with a semicolon ...; (Function () {// our code .. Alert ('Hello! ');})();

It is also a good practice to pass system variables to the plug-in as parameters.

After doing so, window and other system variables have a local reference in the plug-in, which can improve the access speed and performance.

Finally, we get a code with a very safe structure:

; (Function ($, window, document, undefined) {// our code .. // Blah...}) (jQuery, window, document );

As for this undefined, it is a little interesting. In order to get undefined that has not been modified, we did not pass this parameter, but received it when receiving it because it was not actually passed, so the location 'undefined' receives the actual 'undefined. Is it a bit of a hack that deserves a detailed understanding? Of course I did not invent it, but I learned from my previous experiences.

So our plug-in is like this:

; (Function ($, window, document, undefined) {// defines the Beautifier constructor var Beautifier = function (ele, opt) {this. $ element = ele, this. ults = {'color': 'red', 'fontsize': '12px ', 'textrecoration': 'none'}, this. options = $. extend ({}, this. defaults, opt)} // defines the Beautifier method. prototype = {beauent: function () {return this.w.element.css ({'color': this. options. color, 'fontsize': this. options. fontSize, 'textrecoration': this. options. textDecoration}) ;}}// use the Beautifier object in the plug-in $. fn. myPlugin = function (options) {// create the Beautifier object var beautifier = new Beautifier (this, options); // call its method return beautifier. beautify () ;}}) (jQuery, window, document );

A secure, well-structured, and well-organized plug-in has been compiled.

Variable definition and naming

There are no hard rules for naming variables and methods, but it is necessary to follow some conventions to standardize them.

Variable definition: A good way is to define the name of the variable to be used at the beginning of the Code with a var keyword. Variable names are separated by commas. There are two reasons:

First, it is easy to understand and know which variables will be used in the following code. At the same time, the Code is neat and regular, and easy to manage. The variable definition is separated from the logic code;
The second reason is that all variables and function names in JavaScript will be automatically upgraded, also known as the Hoist feature of JavaScript. Even if you embed the definition of variables in the logic Code, during the code parsing and running, the declaration of these variables is promoted to the top of the current scope. Therefore, it is more logical to define the variables at the beginning of a scope. Again, of course, this is just an agreement and is not necessary.

Variables and functions are generally named using CamelCase, that is, the first letter of the first word is lowercase, followed by the first letter of the word, such as resultArray and requestAnimationFrame. For constants, uppercase letters are used, and multiple words are separated by underscores, for example, WIDTH = 100, BRUSH_COLOR = '#00ff00 '. When the variable is of the jQuery type, it is recommended that it start with $, and it will not be used to it, but it will be very convenient after it is often used, because it can be easily distinguished from common variables, as soon as we see it starting with $, we know that it is of the jQuery type and can directly call jQuery-related methods on it, such as var $ element = $ ('A '); later, you can easily use it in the subsequent code and distinguish it from other variables.

Use of quotation marks: Since all these are irrelevant to the plug-in topic, here I would like to say more. Generally, double quotation marks are used in HTML code, while single quotation marks are used in JavaScript, as shown in the following code:

Var name = 'wayou '; document. getElementById ('example '). innerHTML = '<a href = "http: // wayouliu.duapp.com/">' + name + '</a>'; // href = ".. "Double quotation marks are kept in HTML and single quotation marks are kept in JavaScript.

On the one hand, double quotation marks are used in HTML code. On the other hand, when quotation marks are required in JavaScript, it is legal to separate the double quotation marks, unless you use a specifier, that's fine. Furthermore, adhering to such unification can ensure the consistency of the Code style, without the double quotation marks for the strings here, and the single quotation marks for the other places.

Code obfuscation and Compression

After completing the above steps, it is already a small one. You may have noticed that the plug-in you downloaded usually provides a compressed version with 'Min' in the file name. That is, the compressed version of minified. In addition, jQuery is also the compression version provided on the official website, jquery. min. js.

Compression here is not a function compression of the Code. Instead, it replaces the variable names and method function names in the Code with shorter names and deletes comments (if any) delete the blank space between codes and the concentrated version obtained by line feed. At the same time, because the various names in the Code have been replaced, other people can not read and clear their logic, it also plays a role in obfuscation of code.

Benefits of Compression

After the source code is obfuscated and compressed, the size of the source code is greatly reduced, making the code lightweight, accelerating the download speed, and loading both sides faster. For example, the source code of jQuery v1.11.0 is 276kb, and the compressed version is only 94.1kb! The volume is reduced by more than half. The reduction of this volume increases the speed of file downloads.
After compression and obfuscation, can the code still be read? Of course not, so it also plays a role in code protection. Of course, it is only for the case that you have compiled some cool code and do not want others to copy it. For the jQuery community, this is an open-source world. At the same time, there is no substantive way for JavaScript to prevent others from reading your code. After all, there are obfuscation tools, here code compression is more about the effect of the compressed file mentioned above, and at the same time to some extent prevent plagiarism.
Tools

The tools used respect Closure Compiler developed by Google. This tool requires the support of the Java environment. Therefore, you may need to install JRE on the machine before getting Closure for use.

At the same time, there are many online code obfuscation compression tools, which are also very convenient to use. These tools are all searched.

Plug-in release

This step is not necessary, but with a complete attitude, you may also want more people to see or use your plug-in.

First, you need to put the plug-in code on GitHub to create a Service Hook. The purpose of this operation is to update the plug-in later, jQuery can automatically obtain information about the new version and display it on the page of the plug-in center. For details about how to upload code to GitHub, you can download the client tool provided by GitHub to know how to perform the operation, which is very convenient. Just a few clicks on how to create a Service Hook on GitHub. The following section describes how to create an ECS instance.
Create a configuration file in JSON format, including the basic information about the plug-in. For details about the format and parameters, see the plug-in release guide on the jQuery official website. Here is a sample file, is a jQuery plug-in SlipHover I wrote earlier:

{  "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": "liuwayong@gmail.com",    "url": "https://github.com/Wayou"  },  "maintainers": [    {      "name": "Wayou",      "email": "liuwayong@gmail.com",      "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"  }}

Then you can execute the current git code in the root directory of the plug-in to release the plug-in. 0.1.0 is the version number. Each time your plug-in has a new version released, you only need to update the version in the preceding command and create a new tag. In this way, the jQuery plug-in center will automatically obtain the new version information.

$ git tag 0.1.0$ git push origin --tags

GitHub Service Hook

1. Click settings in the menu on the right of the project.

2. Go to the settings page and click 'webhooks & services'

3. Click the 'configure Services' button on the right homepage.

4. A long list is displayed. Find jQuery Plugins and click

5. Click the "update settings" button in the selected box.

Now the settings are complete.

Reference:

  1. JQuery official site Learning Center on plug-in development of the article: http://learn.jquery.com/plugins/
  2. JQuery official site plug-in center: http://plugins.jquery.com/
  3. JQuery official website plug-in release guide: http://plugins.jquery.com/docs/publish/
  4. JavaScript Hoist: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html
  5. Google Web Developer Tool: https://developers.google.com/closure/

Original article: Liu wayong's blog

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.