JavaScript学习总结——jQuery插件开发与发布

Posted 笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript学习总结——jQuery插件开发与发布相关的知识,希望对你有一定的参考价值。

jQuery插件就是以jQuery库为基础衍生出来的库,jQuery插件的好处是封装功能,提高了代码的复用性,加快了开发速度,现在网络上开源的jQuery插件非常多,随着版本的不停迭代越来越稳定好用,在jQuery官网有许多插件:

jQuery1.9.1版源代码中文注释

一、插件开发基础

1.1、$.extend

在jQuery根命名空间下直接调用的方法可以认为是jQuery的静态方法或属性,常常使用$.方法名来调用,使用$.extend这个静态方法可以完成两个功能:

1.1.1、扩展属性或方法给jQuery

比如我们想给jQuery扩展一个用于快速向控制台写入日志的工具方法log,而不需要使用console.log且在没有console.log的浏览器中使用其它的方法替代:

        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $.extend({
                log: function(message) {
                    console.log(message);
                }
            });

            $.log("控制台日志");
        </script>

运行结果:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $.extend({
                log:function(msg){
                    console.log(msg);
                    alert(msg);
                }
            });
            
            $.log("这是日志");
            
            $.constructor.prototype.info=function(msg){
                    console.log(msg);
                    alert(msg);
            };
            
            $.info("这是消息");
        </script>
    </body>
</html>

结果:

1.1.2、扩展对象与深拷贝

用一个或多个其他对象来扩展一个对象,返回被扩展的对象。

如果不指定target,则给jQuery命名空间本身进行扩展。这有助于插件作者为jQuery增加新方法。 如果第一个参数设置为true,则jQuery返回一个深层次的副本,递归地复制找到的任何对象。否则的话,副本会与原对象共享结构。 未定义的属性将不会被复制,然而从对象的原型继承的属性将会被复制。

target,[object1],[objectN]Object,Object,Object V1.0

target:一个对象,如果附加的对象被传递给这个方法将那么它将接收新的属性,如果它是唯一的参数将扩展jQuery的命名空间。

object1:待合并到第一个对象的对象。

objectN:待合并到第一个对象的对象。

[deep],target,object1,[objectN]Object,Object,Object,ObjectV1.1.4

deep:如果设为true,则递归合并。

target:待修改对象。

object1:待合并到第一个对象的对象。

objectN:待合并到第一个对象的对象。

            var x={a:1};
            var y={a:2,b:3};
            var z={b:4,c:5};
            //使用第2个及后的对象扩展前面的对象,如果有则覆盖
            $.extend(x,y,z);
            $.log(x.a+","+x.b+","+x.c);

运行结果: 

除了可以扩展对象的属性,方法也可以扩展。

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var o1={a:1,b:2};
            var o2={b:3,d:4};
            var o3={d:5,e:6};
            
            //用o2扩展对象o1
            $.extend(o1,o2);
            console.log(o1);
            $.extend(o1,o2,o3);
            console.log(o1);
            
            //深拷贝
            var a={n:10};
            var b=a;  //引用,b与a同时指向堆中的对象{n:10}
            b.n=20;
            console.log(a.n);
            console.log(b.n);
            
            //深拷贝:通过序列化与反序列化实现对象
            var c=JSON.parse(JSON.stringify(a));
            console.log("c.n:"+c.n);
            c.n=30;
            console.log("c.n:"+c.n);
            console.log("a.n:"+a.n);
            console.log("b.n:"+b.n);
            console.log(c===a);
            console.log(a===b);
            
            //深拷贝:通过$.extend
            var d=$.extend(true, {}, a);
            console.log("d.n:"+d.n);
            d.n=30;
            console.log("d.n:"+d.n);
            console.log("a.n:"+a.n);
            console.log("b.n:"+b.n);
            console.log(d===a);
            console.log(a===b);
        </script>
    </body>
</html>

结果:

1.2、$.fn.extend

$.fn就是jQuery的原型,$.fn等于jQuery.prototype,$是jQuery的别名。$.fn.extend方法的作用是用于扩展jQuery实例对象,也就是我们从页面中获得的jQuery对象。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>extend</title>
    </head>
    <body>
        <button>按钮1</button>
        <button>按钮2</button>
        <input type="text" value="username"/><input type="text" value="password"/>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
        $.fn.extend({
            show:function(){
                $(this).click(function(){
                    alert($(this).val()||$(this).html());
                });
            },
            log:function(){
                console.log($(this).val()||$(this).html());
            }
        });
        $("button").show();
        $("input[type=text]").log();
        </script>
    </body>

</html>

运行结果:

示例2:

        <script type="text/javascript">
            $.fn.extend({
                display:function(){
                    $(this).click(function(){
                        alert($(this).val()||$(this).html());
                    });
                    return this;
                },
                log:function(){
                    console.log($(this).val()||$(this).html());
                    return this;
                }
            });
            
            $("button,input").display().log().hide(1000).show(100);
            $("div").log().display();
        </script>

1.3、$.fn

在上面的示例中我们通过$.fn扩展了jQuery的原型,让所有的jQuery实例对象都得到的扩展的方法,其它也可以直接修改jQuery.prototype来实现,$.fn是jQuery.prototype的简写,源代码如下:

示例代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>extend</title>
    </head>
    <body>
        <button id="btn1">按钮1</button>
        <button>按钮2</button>
        <input type="text" value="username"/><input type="text" value="password"/>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
           $.fn.bgColor=function(color){
                   this.css("background",color);
           }
           
           jQuery.prototype.color=function(color){
               this.css("color",color);
           }
           
           $("button,input").bgColor("lightGreen");
           $("button,input").color("red");
        </script>
    </body>
</html>

运行结果:

1.4、逗号的特殊作用

如果有多个表达式,且表达式之间由","隔开,整个表达式返回的是最后一个","右侧的表达式的值

示例一:

        <script>
        function f() {
                var i = 1;
                return ++i, i += 1, i += 2;
            }
        console.log(f());
        </script>

结果:

5

示例二:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>

    <body>
        价格:<input type="text" id="price" /><span id="priceMsg"></span>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
        <script type="text/javascript">
            function valid() {
                var price = $("#price");
                var priceMsg = $("#priceMsg");
                var val = "";
                return(val = price.val(), isNaN(val)) ? (priceMsg.html(\'格式错误\'), false) : (priceMsg.html(\'\'), true);
            }

            $("#price").keyup(function(){
                console.log(valid());
            });
        </script>
    </body>

</html>

结果:

二、插件开发

2.1、jQuery插件开发基本模式

jQuery插件开发的基本模式需要有一个私有作用域,javascript中默认没有块级作用域,一般通过闭包+IIFE模拟达到类似效果,在1.3中的示例是存在问题,因他它直接暴露在根命名空间下,可以使用如下办法解决:

            ;(function(method) {
                method(window, window.document, jQuery);
            }(function(win, doc, $) {
                console.log("这是一个私有作用域,IIFE");

                $.fn.yourPluginName = function(options) {

                }
            }));

前置的分号是为了与插件使用前的代码划清界线;两个IIFE表达式的作用是:一个为了立即执行且形成一个私有的块级作用域,另一个是为了将后置的参数前置,方便看到IIFE执行时带的参数。带参数的目的是为了加快查找的速度,提升性能。

插件的命名:

当然一个好的插件应该有一个容易记住且规范的名称,能见名知意且不与别的插件同名冲突,文件的基本命名规范如下:

jQuery.YourPluginName-1.5.js 源代码

jQuery.YourPluginName-1.5.min.js 压缩代码

2.2、获取上下文

插件方法执行范围内可以直接通过this关键字得到上下文,这里的this就是一个jQuery对象,无需使用$(this)将DOM转换成jQuery对象。

            ;
            (function(method) {
                method(window, window.document, jQuery);
            }(function(win, doc, $) {
                console.log("这是一个私有的块级作用域,IIFE");

                $.fn.myPlugin = function(options) {
                    this.css({ //this是一个jQuery对象
                        "color": "blue"
                    });
                }
            }));

            $("button").myPlugin();

运行结果:

上面的示例中是讲$.fn的形式扩展,如果使用$.fn.extend情况还是一样吗?

            ;
            (function(method) {
                method(window, window.document, jQuery);
            }(function(win, doc, $) {
                console.log("这是一个私有的块级作用域,IIFE");

                $.fn.extend({
                    myPlugin2: function(options) {
                        this.css({ //this是一个jQuery对象
                            "background": "lightgreen"
                        });
                    }
                });
            }));
            $("button").myPlugin2();

运行结果:

可见$.fn与$.fn.extend两种方法中的this都是指jQuery对象,这也符合this指向调用他的对象的原则。

2.3、第一个jQuery插件

这是一个Hello World示例,完成一个可以变长的元素插件,指定每次增加长度参数,在指定的HTML元素后增加一个加号点击加号可以将元素加宽指定长度。

jQuery.SuperPlus-1.0.js文件内容如下:

;
(function(method) {
    method(window, window.document, jQuery);
}(function(win, doc, $) {
    $.fn.SuperPlus = function(length) {
        
        $.each(this, function(index, obj) {
            $("<span/>").html("+").css("cursor", "pointer").click(function() {
                $(obj).width($(obj).width() + length);
            }).insertAfter(obj);
        });

    }
}));

HTML页面:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>jQuery插件</title>
    </head>
    <body>
        <button>按钮1</button><br />
        <button>按钮2</button><br />
        <input type="text" value="username" /><br />
        <input type="text" value="password" />
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/SuperPlus/jQuery.SuperPlus-1.0.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $("button").SuperPlus(10);
            $("input").SuperPlus(50);
        </script>
    </body>

</html>

运行结果:

插件中使用each的原因是jQuery选择器选择的内容默认就是一个包装集,中间有多个元素,包装集中含有多个DOM元素,each中的元素就不再是jQuery对象而是一个DOM对象。

练习:$("#div1,#div2").superDiv(50,50,3,"blue");在div1与div2中都添加3个长50,宽50的div,设置背景色为蓝色,点击时div消失,添加的div要求横向排列,间隔为宽高的1/10。

$("#div1,#div2").superDiv({width:50,height:50,color:"red",before:function(){},after:function(){}});

2.4、链式编程

几乎在所有基于“类型”的语言中如果调用一个方法后将对象作为方法参数返回则就会形成链式编程,如:

        return $.each(this, function(index, obj) {
            $("<span/>").html("+").css("cursor", "pointer").click(function() {
                $(obj).width($(obj).width() + length);
            }).insertAfter(obj);
        });

上面的示例中当$.each循环完成后返回this对象,返回的仍然是一个jQuery对象,所以可以继续jQuery编程。

$("button").SuperPlus(10).height(26).width(100).css("color","blue");

运行结果:

2.5、参数与默认值

参数是插件

以上是关于JavaScript学习总结——jQuery插件开发与发布的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript学习总结——jQuery插件开发与发布

jQuery总结

jQuery 版本选择与常见插件库总结

插件总结

Jquery一个快速简洁的JavaScript框架

web前端工程师入门需要学啥?