jquey插件开发

1.概述

jquery插件开发的主要方法有三种:

1、通过$.extend()来扩展jQuery,即在jQuery命名空间下扩展属性,直接在$对象下调用,不需要再dom下调用,也无法在dom元素下调用:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="text">测试</div>
</body>
<script src="jquery-1.8.3.min.js"></script>
<script type="text/javascript">

    //jQuey插件开发方法1,在jQuery命名空间下新增属性

    $.extend({
        sayHello: function(name){
            alert(name);
        }
    });

    $.sayHello('gaoxiong');

    //下面两者都相等,说明 $.fn = $.prototype
    console.log($.fn);
    console.log($.prototype);

    //下面说明了通过 $.extend来扩展jQuery的方法,并不是扩展jquery的原型对象
    console.log($.fn.sayHello);//undefined

    $('#test').sayHello('gaoxiong'); //报错
</script>
</html>

用途:该方法适合用来定义一些辅助方法,类似与$.ajax()等非操作dom元素的方法,为什么时辅助方法?因为现在jquery被利用的主要目的就是操作dom。但这种方式无法利用jQuery强大的选择器带来的便利,要处理DOM元素以及将插件更好地运用于所选择的元素身上,还是需要使用第二种开发方式。

2、$.fn.extend方法扩展 $.prototype

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1 id="h1">测试</h1>
    <h1>测试</h1>
    <h1>测试</h1>
    <h1>测试</h1>
    <h1>测试</h1>
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    
    //jQuery插件方法二:$.fn.extend(),顾名思义,该方法是在jQuery的原型对象上新增一个方法
    $.fn.extend({
        returnThis: function(){
            return this;
        }
    });

    //可以得出,上面的this 是一个集合(类似于数组),集合中包含了所有匹配的元素(这些元素为原生JS dom元素)
    console.log($('#h1').returnThis());
    console.log($('h1').returnThis());

    //将会打印一个原生dom
    console.log($('h1').returnThis()[0])
    //综述:在自定义插件内部中的 this 可以理解为 匹配的元素的集合(jQuery的包装对象),这个集合的原型指向$.fn


    //自定义一个设置字体颜色插件
    $.fn.extend({
        setcolor: function(colorName){
            this.css('color', colorName);
        }
    });
    //所有h1标签变为红色
    $('h1').setcolor('red');

</script>
</html>

3、关于插件内this的指向

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <ul>
        <li>
            <a href="http://www.webo.com/liuwayong">我的微博</a>
        </li>
        <li>
            <a href="http://http://www.cnblogs.com/Wayou/">我的博客</a>
        </li>
        <li>
            <a href="http://wayouliu.duapp.com/">我的小站</a>
        </li>
    </ul>
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    
    //上一节,我们已经知道this 指代jQuery选择器返回的集合(包装对象)
    //$.each()方法可以处理合集中的每个元素,但在each方法内部,this指的是普通的DOM元素,如果调用jQuery的方法那就需要用$来重新包装一下

    //案例,我希望在每个a标签后面显示url地址
    $.fn.extend({
        showUrl: function(){
            this.each(function(){
                console.log(this);//原生dom元素
                $(this).append($(this).attr('href'));
            })
        }
    });

    $('a').showUrl();


    //使用jQuery命名空间时, this的指向为一个函数(包装dom为jQuery包装对象)
    $.extend({
        consoleThis: function(){
            console.log(this);
        }
    })
    $.consoleThis();

</script>
</html>

4、支持链式调用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>测试</h1>
    <h1>测试</h1>
    <h1>测试</h1>
    <h2>测试</h2>
    <h2>测试</h2>
    <h2>测试</h2>
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    
    //jQuery中一个非常简便的方法是支持链式调用
    $.fn.extend({
        setColor: function(colorName){
            //如下的这种写法为便捷写法
            return this.each(function(){
                $(this).css('color', colorName)
            })
        }
    });
    $('h1').setColor('red').css('background', 'blue');

    //未设置链式调用(未在插件中返回this)
    $.fn.extend({
        setFontSize: function(size){
            this.css('font-size', size);
        }
    })
    //因为未在插件中返回this,那么$('h2').setFontSize('50px')为一个undefined,如下会报错
    $('h2').setFontSize('50px').css('background', 'yellow');
    

</script>
</html>

5、设置默认参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>测试</h1>
    <h1>测试</h1>
    <h2>测试</h2>
    <h2>测试</h2>
</body>
<script src='lib/jquery-1.8.3.min.js'></script>
<script type="text/javascript">
    
    //设置默认参数,先学会$.extend(obj1, obj2)
    var DEFAULTS = {
        age: 25,
        name: 'gaoxiong'
    };

    var options = {
        age: 24,
        name: 'jiaojiao'
    };

    var settings = $.extend(DEFAULTS, options);
    console.log(settings);//age=>24, name=>jiaojiao
    console.log(options);//不变
    console.log(DEFAULTS);//与setting一样

    $.fn.extend({
        setColor: function(options){
            var defaults = {
                fontSize: '50px',
                color: 'blue'
            };
            var settings = $.extend(defaults, options);
            return this.css(settings);
        }
    });

    $('h1').setColor();
    $('h2').setColor({
        color: 'red',
        fontSize: '12px'
    })

</script>
</html>

6、保护默认参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>测试</h1>
    <h1>测试</h1>
    <h2>测试</h2>
    <h2>测试</h2>
</body>
<script src='lib/jquery-1.8.3.min.js'></script>
<script type="text/javascript">
    
    //保护好默认参数,在一个插件中,默认参数可能被使用多次,上述方法会修改默认配置参数
    //$.extend({}, defaults, options)避免了默认配置的修改

    var defaults = {
        age: 25,
        name: 'gaoxiong'
    };

    var options = {
        age: 25,
        name: 'jiaojiao'
    };

    var setiings = $.extend({}, defaults, options);
    console.log(setiings); // name => jiaojiao
    console.log(defaults); // name => gaoxiong ,并没有修改defaults

</script>
</html>

7、面向对象的插件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <p>测试</p>
    <p>测试</p>
    <p>测试</p>
    <div>测试</div>
    <div>测试</div>
    <div>测试</div>
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    
    //面向对象的插件开发,当项目变大或者版本迭代时,方便维护,结构清晰化

    //定义一个类
    var Beautifier = function(element, options){
        this.$element = element;
        this.defualts = {
            color: 'red',
            fontSize: '20px',
            textDecoration: 'none'
        };
        this.options = $.extend({}, this.defualts, options);
    };

    //添加原型方法
    Beautifier.prototype = {
        beautify: function(){
            return this.$element.css({
                color: this.options.color,
                fontSize: this.options.fontSize,
                textDecoration: this.options.textDecoration
            })
        }
    };

    //将方法挂载到$.fn
    $.fn.extend({
        beautify: function(options){
            return this.each(function(){
                new Beautifier($(this), options).beautify();
            })
        }
    })

    //使用
    $('p').beautify().css('background', 'blue');
    $('div').beautify({
        color: 'green',
        fontSize: '100px',
        textDecoration: 'decoration'
    })

</script>
</html>

8、命名空间变量污染

不仅仅是jQuery插件的开发,我们在写任何JS代码时都应该注意的一点是不要污染全局命名空间,常用的方法是 用自调用匿名函数包裹你的代码。

匿名函数避免命名空间污染的原理:JavaScript中无法用花括号方便地创建作用域,但函数却可以形成一个作用域,域内的代码是无法被外界访问的。如果我们将自己的代码放入一个函数中,那么就不会污染全局命名空间,同时不会和别的代码冲突。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <p>测试</p>
    <p>测试</p>
    <p>测试</p>
    <div>测试</div>
    <div>测试</div>
    <div>测试</div>
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    (function(){
        var Beautifier = function(element, options){
            this.$element = element;
            this.defualts = {
                color: 'red',
                fontSize: '20px',
                textDecoration: 'none'
            };
            this.options = $.extend({}, this.defualts, options);
        };
        Beautifier.prototype = {
            beautify: function(){
                return this.$element.css({
                    color: this.options.color,
                    fontSize: this.options.fontSize,
                    textDecoration: this.options.textDecoration
                })
            }
        };
        $.fn.extend({
            beautify: function(options){
                return this.each(function(){
                    new Beautifier($(this), options).beautify();
                })
            }
        })
    })();
    $('p').beautify().css('background', 'blue');
    $('div').beautify({
        color: 'green',
        fontSize: '100px',
        textDecoration: 'decoration'
    })
</script>
</html>

9、将系统变量以参数形式传递到插件内部

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    
    //经过我前面8小节的复习,开发插件好像已经完美了,实际上还有一些细节需要处理
    //1. 将这段代码放到页面后,前面别人写的代码没有用分号结尾
    //2. 前面的代码将window, undefined等这些系统变量或者关键字修改掉了

    //第一种情况

    //别人的代码,这里没有使用分号结尾
    var foo = function(){
    }
    //我写的代码
    ;(function(){
          alert('Hello!');
    })();

    //原因:充当自调用匿名函数的第一对括号,与上面别人定义的函数相连,导致组成希望的两个语句 组成了一个语句,出现语法错误
    //解决方法:在匿名函数包裹的圆括号前加分号


    //第二种情况:将系统变量以参数形式传递到插件内部。这样做之后:

    //1. window等系统变量在插件内部就有了一个局部的引用,可以提高访问速度,会有些许性能的提升
    //2. 而至于这个undefined,为了得到没有被修改的undefined,我们并没有传递这个参数,但却在接收时接收了它,因为实际并没有传,所以‘undefined'那个位置接收到的就是真实的'undefined'了。
    //其实上述两个解决办法,在jQuery这个库中本来就有使用到

    //正式版本:一个安全,结构良好,组织有序的插件编写完成。
    ;(function($, window, document, undefined){

        alert('Hello!');

    })(jQuery, window, document);

</script>
</html>

10、代码编写规范

1、变量定义

  • 做法:把将要使用的变量名用一个var关键字一并定义在代码开头,变量名间用逗号隔开
  • 原因:
    • 一是便于理解,了解下面的代码会用到哪些变量,同时代码显得整洁且有规律,也方便管理,变量定义与逻辑代码分开。
    • 二是因为JavaScript中所有变量及函数名会自动提升,也称之为JavaScript的Hoist特性,即使你将变量的定义穿插在逻辑代码中,在代码解析运行期间,这些变量的声明还是被提升到了当前作用域最顶端的,所以我们将变量定义在一个作用域的开头是更符合逻辑的一种做法。

2、变量及函数命名

  • 做法:一般使用驼峰命名法(CamelCase),即首个单词的首字母小写,后面单词首字母大写,比如 showButton。

3、常量命名

  • 做法:对于常量,所有字母采用大写,多个单词用下划线隔开,比如WIDTH=100,BRUSH_COLOR='#00ff00'。

4、当变量为jQuery类型时

  • 当变量是jQuery类型时,建议以$开头,开始会不习惯,但经常用了之后会感觉很方便,因为可以很方便地将它与普通变量区别开来,一看到以$开头我们就知道它是jQuery类型可以直接在其身上调用jQuery相关的方法,比如var $element=$('a'); 之后就可以在后面的代码中很方便地使用它,并且与其他变量容易区分开来。

5、引号的使用

  • 引号的使用:一般HTML代码里面使用双引号,而在JavaScript中多用单引号。

 

posted on 2017-01-16 14:23  码先生  阅读(143)  评论(0编辑  收藏  举报