jquery 插件开发/插件编写$.fn.extend(),$.extend()

jquery插件开发大概有三种方式:
1,$.extend()-在jquery命名空间即jquery本身上添加静态方法;调用,例如:$.myPlugin();而非$('ele').myPlugin();
2,$.fn.extend()-

3,$.widget()-

$.extend({
    createNum:function(name){
        return 'hello '+(name?name:'andy');
    }
});

console.log($.createNum());//hello andy
console.log($.createNum('jack'));// hello jack



html:

    <div id="ex-div">
        <p><b>刘德华</b></p>
        <p><b>张学友</b></p>
        <p><b>黎明</b></p>
        <p><b>郭富城</b></p>
    </div>

以上代码通过$.extend()方法想jquery添加的,直接通过$调用;
但是,发现这种扩展方式无法通过DOM选择器来触发,这个时候我们就需要考虑$.fn.extend()的扩展方式了;
如下,基本格式:
$.fn.sayHello= function(){
    // to do
};
/*
现在我们将页面中的字改变颜色
* */
$.fn.changeColor = function(){
    this.css('color','red');// this 即选中的元素;当前指$('p')
};
// 调用如下:
$('#ex-div p').changeColor();


当然,其实在插件代码里我们经常处理某个具体的元素,而不是一个元素的集合
上面的代码,this指的是jquery选择器返回的集合,我们可以通过jquery中的$.each()方法处理集合中的每个元素了;
但是,在each方法内部,this指代的就是普通的DOM元素了,如果需要调用jquery的方法那就需要用$来重新包装一下;
现在我们来处理,在每个p标签里面加上一个i标签,内容为-香港
$.fn.changeConts = function(){
    //这里对this是用jquery选中的元素\
    var _html = '<i>-香港</i>'
    this.css('color','red');
    this.each(function(){
        //对每个元素进行操作
        $(this).append(_html);
    });
};
$('#ex-div p').changeConts();

我们又丰富了插件,接下来我们继续接受参数的延伸

为了让插件支持链式调用,我们需要return一下;
$.fn.changeConts = function(){
    //这里对this是用jquery选中的元素\
    var _html = '<i>-香港</i>'
    this.css('color','red');
    return this.each(function(){
        //对每个元素进行操作
        $(this).append(_html);
    });
};
$('#ex-div').css('border','1px solid red').find('p').changeConts();


接下来,我们就处理参数的部分;
比如现在我们处理字体的颜色,由用户来定义颜色,如果用户没有定义,我们就取默认值
说明一点:
在处理插件参数的接收上,通常使用jquery的extend方法,上面也提及过,但那是给extend方法传递单个对象的情况下,
这个对象会合并到jquery身上,所以我们就可以在jquery身上调用新合并对象里包含的方法了,如上面的例子;
当给extend方法传递一个以上的参数时,它会将所有到参数对象合并到第一个里.
同时,如果对象中有同名的属性,合并后后面的参数会覆盖前面的;

利用这一点,我们可以在插件里定义一个保存插件参数默认值的对象,同时将接收来的参数对象合并到默认对象上,
最后便实现了用户指定参数使用的值,未指定的参数使用默认值;

我们定义下font-size,允许插件调用的时候设置字体;
$.fn.extend({
    changeConts: function (options) {
        var defaults = {
            'color':'red',
            'fontSize':'12px'
        };
        var setting = $.extend(defaults,options);
        return this.css({
            'color':setting.color,
            'fontSize':setting.fontSize
        });
    }
});
//未指定字体大小的时候,默认值为12px
$('#ex-div p').changeConts({
    'color':'blue'
});
//我们来指定字体大小
$('#ex-div p').changeConts({
    'color':'red',
    'fontSize':'20px'
});


虽然实现了参数的传递,但是我们没有保护包参数

我们可以看到调用extend时,会将defaults的值改变,这样不是我们期望的,我们希望它维持原样,方便其它调用;

一个好的做法是,将一个新的空对象作为$.extend的第一个参数,defaults和用户传递的参数紧跟其后,
这样做的好处就是所有值都合并到这个空对象上,保护了插件里面到默认值;
$.fn.extend({
    changeConts:function(options){
        var defaults = {
            'color':'red',
            'fontSize':'12px'
        };
        var setting = $.extend({},defaults,options);
        return this.css({
            'color':setting.color,
            'fontSize':setting.fontSize
        });
    }
});
$('#ex-div p').changeConts({
    'color':'blue',
    'fontSize':'20px'
});
至此,插件可以接受参数和处理参数后,就可以愉快的编写插件了;
若要编写一个庞大的优雅的插件,我们需要将插件包装到一个对象上,用面向对象的思维进行开发;
如果将需要的重要变量定义到对象的属性上,函数变成对象的方法,当我们需要的时候通过对象获取,
一来方便管理,二来不会影响外部命名空间,因为这些所有的变量名和方法名都是在对象内部;
接下来,我们来优化代码
// 定义Slipactive的构造函数;
function Slipactive(ele,opt){
    this.$element = ele;
    this.dafaults = {
        'color':'red',
        'fontSize':'12px',
        'textDecoration':'none'
    };
    this.options = $.extend({},this.dafaults,opt)
}
Slipactive.prototype = {
    constructor:Slipactive,
    slipactive:function(){
        this.$element.css({
            'color':this.options.color,
            'fontSize':this.options.fontSize,
            'textDecoration':this.options.textDecoration
        });
        return this;
    }
};
// 在插件中使用Slipactive对象
$.fn.extend({
    mySlipa:function(options){
        // 创建Slipactive
        var slipactive = new Slipactive(this,options);
        // 调用方法
        return slipactive.slipactive();
    }
});
$('#ex-div p').mySlipa({
    'color':'blue',
    'fontSize':'30px'
});


以上便是面向对象,也更好维护和理解,以后要添加新方法,只需向对象添加新变量和方法就行,
然后便可以在插件实例化后即可调用新添加的东西
$('#ex-div p').mySlipa({
    'color':'blue',
    'fontSize':'30px',
    'textDecoration':'underline'
});

至此,插件开发已经完毕;
接下来,我们来做些锦上添花的东西;例如优化命名空间,变量等
其实,我们在写js的时候就应该不要污染全局变量;我们可以采用闭包包裹代码
(function(){
    function Slipactive(ele,opt){
        this.$element = ele;
        this.dafaults = {
            'color':'red',
            'fontSize':'12px',
            'textDecoration':'none'
        };
        this.options = $.extend({},this.dafaults,opt)
    }
    Slipactive.prototype = {
        constructor:Slipactive,
        slipactive:function(){
            this.$element.css({
                'color':this.options.color,
                'fontSize':this.options.fontSize,
                'textDecoration':this.options.textDecoration
            });
            return this;
        }
    };
// 在插件中使用Slipactive对象
    $.fn.extend({
        mySlipa:function(options){
            // 创建Slipactive
            var slipactive = new Slipactive(this,options);
            // 调用方法
            return slipactive.slipactive();
        }
    });
})();

自调用匿名函数里面的代码会在第一时间执行;
然后,将系统变量以参数形式传递到插件内部也是个不错的实践;
这样,window等系统变量在插件内部就有了一个局部的引用,可以提高访问效率;
结构如下:
;(function($,window,document,undefiend){
    // to do

})(jQuery,window,document);

最后解释下undefiend
为了得到没有被修改的undefiend,我们并没有传递这个参数,但是却在接收的时候接收了它,
因为实际上并没有传,所以'undefiend'那个位置接收到的就是真正的undefiend了;

至此,完毕!









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值