JQuery plug in development tutorial

  • 2020-03-30 03:14:09
  • OfStack

Extending jQuery plug-ins and methods is powerful and can save a lot of development time. This article will provide an overview of jQuery plug-in development basics, best practices, and common pitfalls.

Introduction to a,

Writing a jQuery plug-in starts by adding jQuery. Fn. The & # 8203; The name of the object property added here is the name of your plug-in:


jQuery.fn.myPlugin = function(){

  //Your own plug-in code

};

Where is the $sign that users love so much? It still exists, but in order to avoid collisions with other JavaScript libraries, it is best to pass jQuery to a self-executing enclosing program, where jQuery is mapped to a $sign to prevent the $sign from being overwritten by other libraries.

(function ($) {
    $.fn.m​​yPlugin = function () {
        //Your own plug-in code
    };
})(jQuery);

In this closed program, we can use the $sign to represent jQuery functions without limit.


Second, the environment

Now we can start writing the actual plug-in code. However, before we can do this, we must have an idea of the environment in which the plug-in resides. In the scope of the plug-in, this keyword represents the jQuery object that the plug-in will execute, which is a common mistake because in other jQuery functions that contain callback, this keyword represents the native DOM element. This often causes developers to mistakenly include this keyword in jQuery, as shown below.


(function ($) {
    $.fn.m​​yPlugin = function () {

        //There is no need to wrap this in a $sign such as $(this) because this is already a jQuery object.
        //$(this) equals $($('#element'));

        this.fadeIn('normal', function () {

            //Here, in the callback function, the this keyword represents a DOM element

        });

    };
})(jQuery);

$('#element').myPlugin();


Basic knowledge

Now that we understand the basics of jQuery plug-ins, let's write a plug-in and do something.


(function ($) {

    $.fn.m​​axHeight = function () {

        var max = 0;

        this.each(function () {
            max = Math.max(max, $(this).height());
        });

        return max;
    };
})(jQuery);

var tallest = $('div').maxHeight(); //Returns the height of the div element with the highest height

This is a simple plug-in that USES.height() to return the height of the largest div element on the page.

4. Maintain Chainability

Many times, the intent of a plug-in is simply to modify the collected elements in some way and pass them on to the next method in the chain. This is the beauty of jQuery's design and one of the reasons it's so popular. Therefore, to maintain a plug-in's chainability, you must ensure that your plug-in returns this keyword.


(function ($) {

    $.fn.lockDimensions = function (type) {

        return this.each(function () {

            var $this = $(this);

            if (!type || type == 'width') {
                $this.width($this.width());
            }

            if (!type || type == 'height') {
                $this.height($this.height());
            }

        });

    };
})(jQuery);

$('div').lockDimensions('width').CSS('color', 'red');

Since the plug-in returns this keyword, it maintains chainability so that elements collected by jQuery can continue to be controlled by jQuery methods such as.css. Therefore, if your plug-in does not return intrinsic value, you should always return this keyword within its scope. In addition, you might infer that the parameters passed to the plug-in will be passed within the scope of the plug-in. Therefore, in the previous example, the string 'width' becomes the type parameter of the plug-in.

Default values and options

For more complex plug-ins and those that offer many options to customize, it's best to have a default setting that can be extended when the plug-in is invoked (by using $.extend). Therefore, instead of calling a plug-in with a large number of parameters, you can call an object parameter that contains the Settings you want to override.


(function ($) {

    $.fn.tooltip = function (options) {

        //Create some default values and extend any options provided
        var settings = $.extend({
            'location': 'top',
            'background-color': 'blue'
        }, options);

        return this.each(function () {

            //Tooltip plug-in code

        });

    };
})(jQuery);

$('div').tooltip({
    'location': 'left'
});

In this example, the location option in the default Settings is overridden when the tooltip plug-in is called, and the backset-color option remains the default, so the final set value to be called is:


{
    'location': 'left',
    'background-color': 'blue'
}

This is a flexible way to provide a highly configurable plug-in without requiring the developer to define all available options.


Vi. Namespace

The proper namespace for your plug-in is a very important part of plug-in development. With the right namespace, your plug-in will have a very low chance of being overwritten by other plug-ins or other code on the same page. Namespaces also make your life easier as a plug-in developer, because they can help you better track your methods, events, and data.

Seven, plug-in method

In any case, a single plug-in should not have multiple namespaces in the jquery.fnjquery.fn object.


(function ($) {

    $.fn.tooltip = function (options) {
        // this
    };
    $.fn.tooltipShow = function () {
        // is
    };
    $.fn.tooltipHide = function () {
        // bad
    };
    $.fn.tooltipUpdate = function (content) {
        // !!!
    };

})(jQuery);

This is discouraged because it messes up the $.fn namespace. To solve this problem, you should collect all the plug-in methods in the object text and call them by passing the string name of the method to the plug-in.

(function ($) {

    var methods = {
        init: function (options) {
            // this
        },
        show: function () {
            // is
        },
        hide: function () {
            // good
        },
        update: function (content) {
            // !!!
        }
    };

    $.fn.tooltip = function (method) {

        //The method call
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method' + method + 'does not exist on jQuery.tooltip');
        }

    };

})(jQuery);

//Call the init method
$('div').tooltip();

//Call the init method
$('div').tooltip({
    foo: 'bar'
});

//Calling the hide method
$('div').tooltip('hide');

//Call the Update method
$('div').tooltip('update', 'This is the new tooltip content!');

This type of plug-in architecture allows you to encapsulate all methods in the parent package, calling them by passing the string name of the method and additional parameters that the method requires. The encapsulation and architectural type of this approach is standard in the jQuery plug-in community and is used by countless plug-ins, including plug-ins and widgets in jQueryUI.

Eight, events,

A little-known feature of the bind method is the ability to bind event namespaces. If your plug-in binds to an event, it is a good idea to namespace the event. This way, when you unbind, you don't interfere with other events of the same type that might have been bound.     You can pass 'by appending a namespace to the event you want to bind to. Namespace> '.


(function ($) {

    var methods = {
        init: function (options) {

            return this.each(function () {
                $(window).bind('resize.tooltip', methods.reposition);
            });

        },
        destroy: function () {

            return this.each(function () {
                $(window).unbind('.tooltip');
            })

        },
        reposition: function () {
            //...
        },
        show: function () {
            //...
        },
        hide: function () {
            //...
        },
        update: function (content) {
            //...
        }
    };

    $.fn.tooltip = function (method) {

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.tooltip');
        }
    };

})(jQuery);

$('#fun').tooltip();
//After a while... .
$('#fun').tooltip('destroy');

In this example, when the tooltip is initialized with the init method, it binds the reposition method to the resize event and gives the reposition fina method a namespace by appending the.tooltip. Later, when the developer needs to destroy the tooltip, we can unbind both the reposition method and the resize event, passing the namespace of the reposition to the plug-in. This enables us to safely unbind events without affecting bindings outside of this plug-in.

Nine, data

Usually during plug-in development, you may want to record or check whether your plug-in has been initialized to an element. Using jQuery's data method is a great way to record variables based on elements. However, compared to data, which records a large number of separations of different names,  Using a single object to hold all variables and reading the object from a separate namespace is a better approach.


(function ($) {

    var methods = {
        init: function (options) {

            return this.each(function () {

                var $this = $(this),
                    data = $this.data('tooltip'),
                    tooltip = $('<div />', {
                        text: $this.attr('title')
                    });

                // If the plugin hasn't been initialized yet
                if (!data) {

                    

                    $(this).data('tooltip', {
                        target: $this,
                        tooltip: tooltip
                    });

                }
            });
        },
        destroy: function () {

            return this.each(function () {

                var $this = $(this),
                    data = $this.data('tooltip');

                // Namespacing FTW
                $(window).unbind('.tooltip');
                data.tooltip.remove();
                $this.removeData('tooltip');

            })

        },
        reposition: function () {
            // ...
        },
        show: function () {
            // ...
        },
        hide: function () {
            // ...
        },
        update: function (content) {
            // ...
        }
    };

    $.fn.tooltip = function (method) {

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.tooltip');
        }

    };

})(jQuery);

Encapsulating the data in an object through a namespace makes it easier to read all plug-in properties from a centralized location.

Summary and best practices

Writing jQuery plug-ins allows you to make libraries that integrate the most useful functionality into reusable code, saving developers time and making development more efficient. When developing jQuery plug-ins, keep in mind:

1. Always wrap in a closed plug-in:

(function($) {

})(jQuery);

2. Do not redundancy wrap this keyword within the functionality of the plug-in
3. This keyword is always returned to maintain chainability unless the plug-in returns a specific value.
Pass an expandable default object parameter instead of a large number of parameters to the plug-in.
Don't name different methods multiple times in a plug-in.
3. Always namespace methods, events, and data.


Related articles: