jQuery Plugin Writing

Keywords: JQuery Javascript JSON xml

The purpose of writing plug-ins is to encapsulate a series of methods or functions that already exist so that they can be reused elsewhere for later maintenance and development efficiency.

jQuery Plugin Type

jQuery There are three main types of plug-ins:
1. Plug-ins encapsulating object methods (object-level component development)
This plug-in encapsulates the object method used to retrieve the jquery Object operations are the most common type of plug-in.This type of plug-in can give you a powerful advantage as a jQuery selector.(
This is the method suspended under the jQuery prototype, so that jQuery object instances obtained through selectors can also share this method, also known as dynamic methods (instance methods)

$.fn.myPlugin = function(){
    //do something
}
//Here $.fn===$.prototype
//For example: addClass(), attr(), etc., you need to create an instance to call
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

2. Plug-ins encapsulating global functions (class-level component development)
Independent functions can be added to the jQuery namespace, for example, the jQuery.noConflict() method is a plug-in inside jQuery that is attached to the kernel as a global function.(
Add a new global function to the jQuery namespace, also known as a static method

jQuery.myPlugin = function(){
    //do something
}
//For example: $.Ajax(), $.extend()
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

3. Selector Plug-in
In some cases, a selector plug-in is required.

Essential points of plug-ins

  • The file name of the jQuery plug-in is recommended to be jQuery. [plug-in name]. js to avoid confusion with other JavaScript library plug-ins.
  • All object methods should be attached to jQuery.fn objects, and all global functions should be attached to jQuery objects themselves
  • Inside the plug-in, this points to the jQuery object currently being acquired through the selector.
  • All elements can be traversed through this.each
  • All method or function plug-ins should end with a semicolon, otherwise problems may occur when compressing.To be more secure, you can even add a semicolon to the plug-in header to avoid the impact of other people's code irregularities on the plug-in.
  • The plug-in should return a jQuery object to ensure that the plug-in can be chained.

Common Plug-in Forms

//Note that for better compatibility, there is a semicolon before you start
;(function($){//Use $here as a parameter to an anonymous function
    //Place your code here and use $as an abbreviated alias for jQuery
    //Define a local variable foo that is accessible only internally but not externally
    var foo;
    var bar = function(){
    //Foo can be accessed by functions inside anonymous functions, even when bar() is called outside of anonymous functions, foo can also be accessed inside bar(). However, direct access to foo outside anonymous functions is not possible.
    }
    $.BAR = bar;
    //This statement allows the function bar () inside an anonymous function to escape to a globally accessible range so that it can be called outside the anonymous function, jQuery.BAR() to access the internally defined function bar (), and the internal function bar () to access the variable foo within the anonymous function
})(jQuery);//Here, jQuery is passed as an argument to the anonymous function
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

No semicolon at the beginning of the plugin

For instance:

<script type="text/javascript">
    var fn = function(){
        console.log("I don't end with a semicolon");
    }
    (function(){
        console.log("The function above does not end with a semicolon, which prevents me from executing it correctly");
    })();
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

 
Specific note: The above example shows that it is necessary to add a semicolon before the plug-in.

Closure in Plugin

With regard to closures, ECMAScript defines them as allowing the use of internal functions (i.e., function definitions and function expressions are within the body of functions of another function), and these internal functions can access all local variables, parameters, and other internal functions declared in the external function in which they reside, when one of these internal functions contains them.When called outside of an external function, a closure is formed.That is, the internal function is executed when the external function returns.When this internal function is executed, it must have access to the local variables, parameters, and other internal functions of its external function.The values of these local variables, parameters, and function declarations are those returned by external functions, but are also affected by internal functions.

Closure allows us to access and modify local variables in contained functions.
By taking advantage of the closure feature, you can avoid internal temporary variables affecting the global space, and you can continue to use $as an alias for jQuery within your plug-in.

Provide default options for plug-ins

Plugins should have some options that developers can set on their own, so it is necessary to provide default options for recovery.You can set these options through jQuery's extension function:

var defaults = {//Default configuration parameters
        'container' : '#container',//container
        'sections' : '.section',//Subcontainers
        'easing' : 'ease',//Special effects, ease-in,ease-out,linear
        'duration' : 1000,//Time of each animation execution
        'pagination' : true,//Whether to display paging
        'loop' : false,//Is it circular
        'keyboard' : true,//Whether keyboard is supported
        'direction' : 'vertical',//Sliding direction horizontal,vertical,
    };

opts = $.extend({}, defaults , options||{});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

JQuery provides two methods for extending jQuery functionality: jQuery.extend() and jQuery.fn.extend(). Both methods accept a parameter of type Object.Object object's name/value pair represents function or method name/function body, respectively.
Specific note: The first parameter of the $.extend() method is an empty object, not the defaults parameter, because it protects the default parameter values from being modified by user-defined parameters.

Usage of jQuery.extend()

The jQuery.extend() method can be used to extend existing object objects as well as jQuery objects.(
Add attributes of objects to jQuery objects
Demo:

<script type="text/javascript" src="jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
    var obj1 = {
        apple:0,
        banana:{weight:52,price:100},
        cherry:97
    };
    jQuery.extend(obj1);//This adds the properties of the obj1 object to the jQuery object
    console.log(jQuery.apple);//0
    console.log(jQuery.banana);//Object {weight: 52, price: 100}
    console.log(jQuery.cherry);//97
});
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Extend an object with one or more other objects and return the extended object.(
Demo:

<script type="text/javascript" src="jquery-2.1.4.js"></script>
<script type="text/javascript">
/*
This example combines obj1 and obj2 objects, modifies and returns the obj1 object
 */
$(function(){
    var obj1 = {
        name:"lisi",
        job:"worker",
        age:22
    };
    var obj2 = {
        name:"wangwu",
        age:100,
        address:"Dalian"
    };
    $.extend(obj1,obj2);//The default first parameter is false, which means shallow copy
    console.log(obj1);//Object {name:'wangwu', job:'worker', age: 100, address:'Dalian'}
});
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

Shallow copy:

<script type="text/javascript" src="jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
    var obj1 = {
        apple:0,
        banana:{weight:52,price:100},
        cherry:97
    };
    var obj2 = {
        banana:{price:200},
        durian:100
    };
    var obj = $.extend(obj1,obj2);
    var obj1 = $.extend(false,obj1,obj2);//Default first parameter is false, shallow copy
    console.log(JSON.stringify(obj));//{"apple":0,"banana":{"price":200},"cherry":97,"durian":100}
    console.log(JSON.stringify(obj1));
    //As you can see from the output, the banana key value has been replaced
});
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Deep copy: nested child objects are also recursively merged

<script type="text/javascript" src="jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
    var obj1 = {
        apple:0,
        banana:{weight:52,price:100},
        cherry:97
    };
    var obj2 = {
        banana:{price:200},
        durian:100
    };
    var obj = $.extend(true,obj1,obj2);//The first parameter true represents a deep copy
    console.log(JSON.stringify(obj));//{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}
//A deep copy is a recursive merge that overrides existing attribute values and adds none
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Comparison of results in deep and shallow copies:

//deep copy
{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}
//shallow copy
//{"apple":0,"banana":{"price":200},"cherry":97,"durian":100}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

The result of shallow copy directly replaces the value of banana, while deep copy merges and modifies the value of banana instead of simply replacing it directly.(
The jQuery.extend() method is often used to set a series of default parameters for the plug-in method.
Demo:

<script type="text/javascript" src="jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
    function fn(options){
        options = $.extend({
            name:"bar",
            length:5,
            dataType:"xml"/*Default parameter settings*/
        },options);
        return options;
    }
    console.log(fn({name:"a",length:6,dataType:"json"}));//Object {name: "a", length: 6, dataType: "json"}
    console.log(fn({name:"b",length:7}));//Object {name: "b", length: 7, dataType: "xml"}
    console.log(fn({name:"c"}));//Object {name: "c", length: 5, dataType: "xml"}
    console.log(fn());//Object {name: "bar", length: 5, dataType: "xml"}
});
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

When we call the fn() method, we set the corresponding value in the passed parameter options object, then the set value is used, otherwise the default value is used.By using the $.extend() method, it is easy to override the default value with the parameters passed in.

jQuery Plugin Writing

jQuery.color plug-in

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>jQuery.color Plug-in unit</title>
    <style type="text/css">
        .red{
            color: red;
        }
    </style>
</head>
<body>
<div class="red">red</div>
<div class="blue" style="color: blue;">blue</div>
<div class="yellow" style="color:yellow;">yellow</div>
<script type="text/javascript" src="jquery-2.1.4.js"></script>
<script type="text/javascript" src="jQuery.color.js"></script>
<script type="text/javascript">
//Plug-in Application
$(function(){
    console.log($("div").color("red"));
});
</script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

jQuery.color.js

;(function($){
    $.fn.extend({
        "color":function(value){
            return this.css("color",value);//Set Font Color Value
        }
    });
})(jQuery);
/*
This method is given a parameter value, which is used to set the value if the value is passed when the method is called
 Font color, otherwise get the value of the font color of the matching element
 */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Object-Oriented Plug-in Development

There's a question here: Why do you need an object-oriented way to develop plug-ins?In order to solve this problem, I also checked a lot of data and finally understood the reason.(
Because if you don't, you might need a method to define a function, another method to define a function, and a variable to define variables that are scattered around your code irregularly.(
It is still an old problem, inconvenient to maintain and not clear enough.Of course, these issues are not evident when the code is small.(
If the important variables needed are defined on the properties of the object, the function becomes the method of the object, which is acquired through the object when we need it, for convenience in management, and for exterior namespaces, because all these variable names and method names are inside the object.(
The object-oriented way of development is conducive to better maintenance and understanding of plug-ins. In the future, to add new functions and methods, simply add new variables and methods to the objects, and then call the newly added things after instantiation in the plug-ins.

Demo:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <style type="text/css">
    a{
        display: block;
        margin-bottom: 10px;
        text-decoration: none;
    }
    </style>
</head>
<body>
<a href="www.123.com">Use Baidu Search</a>
<a href="www.456.com">Googling</a>
<a href="www.789.com">A must-have</a>
<script type="text/javascript" src="../jquery-1.11.2.min.js"></script>
<script type="text/javascript">
var changeStyle = function(ele,options){
    this.ele = ele;
    this.defaults = {
        'color':'red',
        'fontSize':'30px'
    };
    this.settings = $.extend({},this.defaults,options);
};
changeStyle.prototype = {
    doChange:function(){
        return this.ele.css({
            'color':this.settings.color,
            'fontSize':this.settings.fontSize
        });
    }
};
//Add a method to jQuery's prototype, that is, add an instance method
// $.fn.extend({
//  //styleChange is the name of the plugin we defined
//  styleChange:function(options){
//      var obj = new changeStyle(this,options);
//      return obj.doChange();
//  }
// });
$.fn.styleChange = function(options){
    var obj = new changeStyle(this,options);
        return obj.doChange();
};
$("a").styleChange({
    'color':'green',
    'fontSize':'20px'
});
</script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

Preventing global variable pollution

Not only is this a concern in the development of jQuery plug-ins, but one thing we should note when writing any JS code is not to pollute global variables.As the amount of code increases, it can be difficult to maintain and easily conflict with code written by others if you intentionally or unintentionally define variables globally.(
For example, you add a variable status to the global window object in your code to store the state, and a library written by another person is referenced in the page. You also add such a variable with the same name to the global. The final result is definitely not what you want.So, in general, we don't define variables as global.(
Solution: Use self-executing anonymous functions to wrap the plug-in code so that you can safely use it anywhere without any conflicts.We know JavaScript Scopes cannot be easily created in curly brackets, but functions can form private scopes where code cannot be accessed.If we put our code into a function, it won't pollute the global namespace, and it won't conflict with other code.

<script type="text/javascript">
//Place defined plug-ins in a self-executing anonymous function
(function($,window,undefined){
    var changeStyle = function(ele,options){
    this.ele = ele;
    this.defaults = {
        'color':'red',
        'fontSize':'30px'
    };
    this.settings = $.extend({},this.defaults,options);
};
changeStyle.prototype = {
    doChange:function(){
        return this.ele.css({
            'color':this.settings.color,
            'fontSize':this.settings.fontSize
        });
    }
};
$.fn.styleChange = function(options){
    var obj = new changeStyle(this,options);
        return obj.doChange();
};
$("a").styleChange({
    'color':'green',
    'fontSize':'20px'
});
})(jQuery,window,undefined);
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

Another benefit of writing this is that the code inside an anonymous function is executed the first time it is called, and when the page is ready, the above code prepares the plug-in for use in subsequent code.(
One more thing to note in the code above is that we passed jQuery objects, window objects, and undefined as arguments to anonymous functions.(
In this way, system variables such as window have a local reference inside the plug-in, which can improve access speed and help improve performance (we all know that global variable lookup is the slowest).(
Reference Blog:
10 Suggestions for Creating a Better jQuery Plug-in 
jQuery Plugin Development Mode 
Deep understanding of jQuery plug-in development

Posted by mikelmao on Wed, 19 Jun 2019 09:40:36 -0700