美文网首页
JQuery 插件的编写

JQuery 插件的编写

作者: lp0124 | 来源:发表于2017-06-16 00:44 被阅读0次

    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('<div class="'+opts.container_class.slice(1)+'">'+
                            '<div class="'+opts.container_class.slice(1)+'-box">'+
                                '<div class="'+opts.no_data_class.slice(1)+'">'+opts.no_data_msg+'</div>'+
                            '</div>'+
                         '</div>');
                });
            }
        });
        //默认参数
        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) {}
    

    完整的插件代码如下:

    <style>
    .container-options{position:absolute;min-width:100%;left:0;background:#fff;z-index:1;display:none}
    .container-options .container-options-box{margin-top:-1px;border:1px solid #ccc;max-height:150px;overflow:auto}
    .container-options .item,.container-options .no-data{text-align:center;transition:all .3s;cursor:pointer;line-height:1;padding:8px 0;text-align:center}
    .container-options .item:hover{color:#fff;background:#eb6120}
    .container-options .no-data{display:none}
    </style>
    
    (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('<div class="'+opts.container_class.slice(1)+'">'+
                                    '<div class="'+opts.container_class.slice(1)+'-box">'+
                                        '<div class="'+opts.no_data_class.slice(1)+'">'+opts.no_data_msg+'</div>'+
                                    '</div>'+
                                '</div>');
                    // 为当前输入框绑定 事件监听,动态获取值
                    $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.length; i++){
                    list += '<div class="'+opts.option_class.slice(1)+'" data-id="'+response.data.list[i].id+'">'+response.data.list[i].name+'</div>';
                }
                $(opts.container_class+'-box').append(list);
            }
        }
        //私有方法
        function isValid(options) {
            return !options || (options && typeof options === "object") ? true : false;
        }
    })(window.jQuery);
    

    相关文章

      网友评论

          本文标题:JQuery 插件的编写

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