JQuery 插件的编写

jquery的插件机制

为了方便用户创建插件,jquery提供了.extend()和.fn.extend()方法。
.extend(object) ,用于扩展jQuery类本身,也就是用来在jQuery类/命名空间上增加新函数,或者叫静态方法. 例如 jquery内置的 ajax方法都是用.ajax()这样调用的,有点像 “类名.方法名” 静态方法的调用方式。

$.extend({
    minValue: function (a, b) {
        // 比较两个值,返回最小值
        return a < b ? a : b;
    }
});
//调用
var i = 100; j = 101;
var min_value = $.minValue(i, j); // min_value 等于 100
$.extend([deep], target, object1, [objectN]);
用一个或多个其他对象来扩展一个对象,返回被扩展的对象。
参数
    deep:可选。如果设为true,则递归合并。
    target:待修改对象,如果不指定target,则给jQuery命名空间本身进行扩展。
    obj1:待合并到第一个对象的对象
    objectN:可选。待合并到第一个对象的对象。
例:
    var obj1 = { a: false, b: 1, c: "abc" }; 
    var obj2 = { a: true, c: "def" }; 
    $.extend(obj1, obj2);
    // 输出 obj1 = { a: true, b: 1, c: "def" }
套路:
    var opts = $.extend({}, defaluts, options);
    // 用自定义插件参数去覆盖插件的默认参数

$.fn.extend(object)扩展 jQuery 元素集来提供新的方法(通常用来制作插件)。

$.fn = $.prototype = {
   init: function( selector, context ) {.....};
};

原来 .fn =.prototype,也就是jQuery对象的原型。那jQuery.fn.extend()方法就是扩展jQuery对象的原型方法。

自执行的匿名函数/闭包

匿名函数最大的用途是创建闭包(这是JavaScript语言的特性之一),并且还可以构建命名空间,以减少全局变量的使用。

封装JQuery插件

接下来我们一起来写个 监听文本框,动态显示下拉选项 (类似搜索提示)插件

1.定一个闭包区域,防止插件"污染"

//闭包限定命名空间
(function ($) {
    // do something
})(window.jQuery);

2.jQuery.fn.extend(object)扩展jquery 方法,制作插件

//闭包限定命名空间
(function ($) {
    $.fn.extend({
        getAjaxOption:function(options){
            // do something
        }
    });
})(window.jQuery);

3.给插件默认参数,实现 插件的功能
//闭包限定命名空间

(function ($) {
    $.fn.extend({
        getAjaxOption: function (options) {
            var opts = $.extend({}, defaluts, options); // 使用jQuery.extend 覆盖插件默认参数
            // 为body绑定事件,判断当点击别的区块,隐藏下拉选项区块
            $(document).on('click',function(event){
                event = window.event || event; 
                var target = $(event.srcElement || event.target);  
                var is_select = opts.container_class+' *,'+opts.container_class+','+opts.target_class+' *,'+opts.target_class;
                if(!target.is(is_select)){
                    $(opts.container_class).hide();
                }
            })
            return this.each(function () {  // 这里的this 就是 jQuery对象,这里 return 为了支持链式调用
                // 遍历所有选中的dom
                var $this = $(this); // 获取当前dom 的 jQuery对象,这里的this是当前循环的dom
                console.log(opts);  // opts为当前所有的配置项
                // 接下来,在当前dom下生成下拉选项的dom元素
                $this.parent().css('position','relative');
                $this.addClass(opts.target_class.slice(1))
                     .after('
'+ '
'+ '
'+opts.no_data_msg+'
'+ '
'+ '
'); }); } }); //默认参数 var defaluts = { container_class:'.container-options', // 下拉选项容器class target_class:'.ajaxOptionThis', // 当前dom的标识class option_class:'.item', // 生成的下拉选项的class no_data_class:'.no-data', // 无数据时对应项的class no_data_msg:'未找到相关数据', // 无数据时对应项显示的文字信息 ajax_url:'******', // 请求的地址 ajax_type:'get', // 请求的类型 ajax_data:{ // 请求的额外参数 city : 'zg', page : 1 }, ajax_keyword_name:'kw', // 请求的关键词的name值,value值固定为当前文本框的值 }; })(window.jQuery);

5.插件私有方法
有些时候,我们的插件需要一些私有方法,不能被外界访问。

//私有方法,检测用户传进来的参数是否合法
function isValid(options) {
    return !options || (options && typeof options === "object") ? true : false;
}

6.公共方法 给别人来扩展你的插件 或者 返回一些回调api

// 公共方法
// 当点击了选项后的回调函数,$this为当前输入框,that为当前点击的选项,opts为插件的配置项集合
$.fn.getAjaxOption.clickCallback = function ($this,that,opts) {}
// 当ajax返回成功后执行的回调函数,$this为当前输入框,response为后端返回的数据,opts为插件的配置项集合
$.fn.getAjaxOption.successCallback = function ($this,response,opts) {}

完整的插件代码如下:


(function ($) {
    $.fn.extend({
        getAjaxOption: function (options) {
            //检测用户传进来的参数是否合法
            if (!isValid(options)) return this;
            var opts = $.extend({}, defaluts, options);
            $(document).on('click',function(event){
                event = window.event || event; 
                var target = $(event.srcElement || event.target);  
                var is_select = opts.container_class+' *,'+opts.container_class+','+opts.target_class+' *,'+opts.target_class;
                if(!target.is(is_select)){
                    $(opts.container_class).hide();
                }
            })
            return this.each(function () { 
                var $this = $(this);
                $this.parent().css('position','relative');
                $this.addClass(opts.target_class.slice(1))
                     .after('
'+ '
'+ '
'+opts.no_data_msg+'
'+ '
'+ '
'); // 为当前输入框绑定 事件监听,动态获取值 $this.on('input',function(){ var data = {}; data[opts.ajax_keyword_name] = $.trim($this.val()); data = $.extend({}, opts.ajax_data, data); if( data[opts.ajax_keyword_name].length <=0 ){ return false; } $.ajax({ type:opts.ajax_type, url :opts.ajax_url, data: data, success: function(response){ $.fn.getAjaxOption.successCallback($this,response,opts); } }); }) // 为下拉选项的每一项绑定click事件 $(opts.container_class).on('click',opts.option_class,function(){ $.fn.getAjaxOption.clickCallback($this,this,opts); }) }); } }); //默认参数 var defaluts = { // 容器dom container_class:'.container-options', target_class:'.ajaxOptionThis', option_class:'.item', no_data_class:'.no-data', no_data_msg:'未找到相关数据', ajax_url:'*****', ajax_type:'get', ajax_data:{ city : 'zg', page : 1 }, ajax_keyword_name:'kw', }; //公共方法 $.fn.getAjaxOption.clickCallback = function ($this,that,opts) { $this.val($(that).text()); $(opts.container_class).hide(); } $.fn.getAjaxOption.successCallback = function ($this,response,opts) { $(opts.container_class).show().find(opts.option_class).remove(); if(response.data == "no result"){ $('.no-data',opts.container_class).show(); }else{ $('.no-data',opts.container_class).hide(); var list = ''; for (var i=0; i'+response.data.list[i].name+'
'; } $(opts.container_class+'-box').append(list); } } //私有方法 function isValid(options) { return !options || (options && typeof options === "object") ? true : false; } })(window.jQuery);

你可能感兴趣的:(JQuery 插件的编写)