美文网首页
jQuery插件扩展

jQuery插件扩展

作者: 小丘啦啦啦 | 来源:发表于2019-04-10 09:28 被阅读0次

    一、jQuery的扩展性
    jQuery,除了对JavaScript进行封装让写法、功能实现更简单,特别是选择器抓取DOM元素(虽然有了vue等插件会减少操作dom的需求)和ajax调用;而且,它的可扩展性也是受众多开发者青睐的,从而可以建立起自己公司的生态系统。
    二、扩展方式
    1、通过$.extend()扩展
    仅仅是在jQuery命名空间或者说是jQuery身上添加了一个静态方法而已。
    通过调用$.extend()添加的函数直接通过$符号调用($.func()),不需要抓取DOM元素($('#id').func())。

    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <script typet="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
        </head>
        <body>
            <script>
                $.extend({
                    sayHello(name){
                        console.log(`Hello ${name}`);
                    }
                });
                $.sayHello('qiurx');   //Hello qiurx
            </script>
        </body>
    </html>
    

    这种方法可以简单的添加一个jQuery插件,通常用来定义一些辅助方法,例如console.log打印自定义日志。用另一种写法:

    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <script typet="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
        </head>
        <body>
            <script>
                $.logDate = function(msg){
                    var now = new Date();
                    var y = now.getFullYear();
                    var m = now.getMonth()*1+1;
                    var d = now.getDate();
                    var hh = now.getHours();
                    var mm = now.getMinutes();
                    var ss = now.getSeconds();
                    console.log(`${y}-${m}-${d} ${hh}:${mm}:${ss}————${msg}`);
                }
                $.logDate('异步调用开始');   //2019-4-8 19:46:8————异步调用开始
            </script>
        </body>
    </html>
    

    但这种方法无法利用jQuery强大的选择器带来的便利。
    2、通过$.fn扩展
    jQuery扩展最常用的一种方法。
    $.fn的插件执行函数中,this指向jQuery选择器选中的元素,是一个jQuery类型的集合。集合已经是jQuery包装类型了,可以直接调用jQuery的其他方法,也不需要用$重新包装了。

    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <script typet="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
        </head>
        <body>
            <a href="http://baidu.com">百度</a>
            <script>
                $.fn.colorRed = function(){
                    this.css('color','red');
                }
                $('a').colorRed();   //此插件内部的this即为$('a')
            </script>
        </body>
    </html>
    

    $.fn添加的插件内部this指向jQuery选择器返回的集合,可以通过$.each()操作集合中的每个元素。注意,$.each()方法内部,this指向集合中的每个元素,是普通的DOM元素,这时候要调用jQuery的方法需要用$重新包装下。
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <script typet="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
        </head>
        <body>
            <li><a href="http://baidu.com">百度</a></li>
            <li><a href="https://www.json.cn/">JSON解析</a></li>
            <script>
                $.fn.showHref = function(){
                    this.each(function(){
                        //此处this指向每个普通的DOM元素,要重新$获取
                        $(this).append($(this).attr('href'));   
                    });
                }
                $('a').showHref();   
            </script>
        </body>
    </html>
    

    3、通过$.widget()应用jQuery UI的部件工厂方式创建扩展
    略。
    三、$.fn的链式调用
    jQuery一个很好的地方就是支持链式调用,选择器抓取DOM元素后可以不断的调用其他方法。要让插件支持这种调用,只需要return一下。
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <script typet="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
        </head>
        <body>
            <li><a href="http://baidu.com">百度</a></li>
            <li><a href="https://www.json.cn/">JSON解析</a></li>
            <script>
                $.fn.colorRed = function(opt) {
                    var defaults = {
                        'color' : 'red',
                        'fontSize' : '12px'
                    }
                    $.extend(defaults,opt);   //让插件接收参数,有则合并取参数内容,没有则用默认值
                    return this.css(defaults);
                }
                $.fn.showHref = function() {
                    this.each(function() {
                        $(this).append($(this).attr('href'));
                    });
                    return this;
                }
                $('a').colorRed({'color':'blue'}).showHref();
            </script>
        </body>
    </html>
    

    四、面向对象思维开发插件
    首先为什么要有面向对象思维。需要一个方法,就去定义一个function;需要一个变量,就随意在代码各处定义全局变量。这种做法不方便维护,也不清晰,虽然在代码规模小的时候体现不明显。
    • 如果将重要属性和方法都定义在对象上,需要时就通过对象来调用,这样方便管理,而且也减少影响外部的命名空间可能性(随着代码增多,全局属性和方法多了在全局中可能会出现重名覆盖,和别人冲突,难维护)。
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <script typet="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
        </head>
        <body>
            <li><a href="http://baidu.com">百度</a></li>
            <li><a href="https://www.json.cn/">JSON解析</a></li>
            <script>
                var Beautiful = function(ele, opt) { //定义一个专门用来美化的类(构造函数)
                    this.$ele = ele;
                    var defaults = {
                        'color': 'red',
                        'fontSize': '12px',
                        'textDecoration': 'none'
                    }
                    this.options = $.extend({}, defaults, opt);
                }
                Beautiful.prototype = {   //定义原型方法
                    beautify(){
                        return this.$ele.css({
                            'color': this.options.color,
                            'fontSize': this.options.fontSize,
                            'textDecoration': this.options.textDecoration
                        });
                    }
                }
                $.fn.myPlugin = function(opt) {   //定义一个插件
                    var beautifier = new Beautiful(this,opt);   //调用构造函数创建对象
                    return beautifier.beautify();   //调用对象方法
                }
                $('a').myPlugin({
                    'color': 'yellow',
                    'fontSize': '20px',
                });
            </script>
        </body>
    </html>
    

    像这样改造,以后需要新属性方法时就直往构造函数添加,然后在插件里实例化后调用。
    五、自调用匿名函数包裹代码
    为了避免污染全局命名空间,不到万不得已尽量不把变量定义成全局的;还有一个方法,用自调用匿名函数包裹代码,这样可以安全的用于任何地方,绝对不会冲突。
    • js无法用花括号快捷的创建创建作用域,但是函数可以函数内无法被外部访问(除非闭包返回出去)。将代码写在一个函数中,就不会污染全局命名空间了,然后再自调用实现内部代码(也可以直接把代码写到jQuery的插件定义代码中去$.fn...,但这样让插件定义显得臃肿,插件定义代码应该更注重调用和如何与jQuery实现互动)。
      修改为自调用匿名函数形式:
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <script typet="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
        </head>
        <body>
            <li><a href="http://baidu.com">百度</a></li>
            <li><a href="https://www.json.cn/">JSON解析</a></li>
            <script>
                //避免前面的代码没有加(;)结尾,与自调用匿名函数相连报错
                ;(function (){   //定义一个匿名函数
                        var Beautiful = function(ele, opt) { //定义一个专门用来美化的类(构造函数)
                        this.$ele = ele;
                        var defaults = {
                            'color': 'red',
                            'fontSize': '12px',
                            'textDecoration': 'none'
                        }
                        this.options = $.extend({}, defaults, opt);
                    }
                    Beautiful.prototype = {   //定义原型方法
                        beautify(){
                            return this.$ele.css({
                                'color': this.options.color,
                                'fontSize': this.options.fontSize,
                                'textDecoration': this.options.textDecoration
                            });
                        }
                    }
                    $.fn.myPlugin = function(opt) {   //定义一个插件
                        var beautifier = new Beautiful(this,opt);   //调用构造函数创建对象
                        return beautifier.beautify();   //调用对象方法
                    }
                }   
                )();   //定义函数后自调用
                $('a').myPlugin({
                    'color': 'yellow',
                    'fontSize': '20px',
                });
            </script>
        </body>
    </html>
    

    自调用匿名函数中的代码会在第一时间执行。
    六、良好习惯
    1、习惯性在代码开头加上分号(;),避免前面的代码没以分号结尾导致代码运行报错。

    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <script typet="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
        </head>
        <body>
            <script>
                var foo = function() {
                    //别人的代码
                } //注意这里没有用分号结尾
    
                //开始我们的代码。。。
                (function() {    
                    alert('Hello!');
                })();
            </script>
        </body>
    </html>
    

    匿名函数的第一个括号与前面别人的函数相连导致了报错,所以习惯性在我们的代码前面加个分号。

    ;(function(){
        //我们的代码。。
        alert('Hello!');
    })();
    

    2、将系统变量以参数形式传递到插件内部也是个不错的实践。
    window等系统变量在插件内部就有了一个局部的引用,可以提高访问速度,会有些许性能的提升。

    ;(function($,window,document,undefined){
        //我们的代码。。
        //blah blah blah...
    })(jQuery,window,document);
    

    至于这个undefined参数,为了得到没有被修改的undefined,我们并没有传递这个参数,但却在接收时接收了它,因为实际并没有传,所以‘undefined’那个位置接收到的就是真实的'undefined'了。

    相关文章

      网友评论

          本文标题:jQuery插件扩展

          本文链接:https://www.haomeiwen.com/subject/cunpiqtx.html