JQuery 插件的編寫

jquery的插件機(jī)制

為了方便用戶創(chuàng)建插件,jquery提供了.extend()和.fn.extend()方法。
.extend(object) ,用于擴(kuò)展jQuery類本身,也就是用來在jQuery類/命名空間上增加新函數(shù),或者叫靜態(tài)方法. 例如 jquery內(nèi)置的 ajax方法都是用.ajax()這樣調(diào)用的,有點(diǎn)像 “類名.方法名” 靜態(tài)方法的調(diào)用方式。

$.extend({
    minValue: function (a, b) {
        // 比較兩個(gè)值,返回最小值
        return a < b ? a : b;
    }
});
//調(diào)用
var i = 100; j = 101;
var min_value = $.minValue(i, j); // min_value 等于 100
$.extend([deep], target, object1, [objectN]);
用一個(gè)或多個(gè)其他對(duì)象來擴(kuò)展一個(gè)對(duì)象,返回被擴(kuò)展的對(duì)象。
參數(shù)
    deep:可選。如果設(shè)為true,則遞歸合并。
    target:待修改對(duì)象,如果不指定target,則給jQuery命名空間本身進(jìn)行擴(kuò)展。
    obj1:待合并到第一個(gè)對(duì)象的對(duì)象
    objectN:可選。待合并到第一個(gè)對(duì)象的對(duì)象。
例:
    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);
    // 用自定義插件參數(shù)去覆蓋插件的默認(rèn)參數(shù)

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

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

原來 .fn =.prototype,也就是jQuery對(duì)象的原型。那jQuery.fn.extend()方法就是擴(kuò)展jQuery對(duì)象的原型方法。

自執(zhí)行的匿名函數(shù)/閉包

匿名函數(shù)最大的用途是創(chuàng)建閉包(這是JavaScript語言的特性之一),并且還可以構(gòu)建命名空間,以減少全局變量的使用。

封裝JQuery插件

接下來我們一起來寫個(gè) 監(jiān)聽文本框,動(dòng)態(tài)顯示下拉選項(xiàng) (類似搜索提示)插件

1.定一個(gè)閉包區(qū)域,防止插件"污染"

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

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

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

3.給插件默認(rèn)參數(shù),實(shí)現(xiàn) 插件的功能
//閉包限定命名空間

(function ($) {
    $.fn.extend({
        getAjaxOption: function (options) {
            var opts = $.extend({}, defaluts, options); // 使用jQuery.extend 覆蓋插件默認(rèn)參數(shù)
            // 為body綁定事件,判斷當(dāng)點(diǎn)擊別的區(qū)塊,隱藏下拉選項(xiàng)區(qū)塊
            $(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對(duì)象,這里 return 為了支持鏈?zhǔn)秸{(diào)用
                // 遍歷所有選中的dom
                var $this = $(this); // 獲取當(dāng)前dom 的 jQuery對(duì)象,這里的this是當(dāng)前循環(huán)的dom
                console.log(opts);  // opts為當(dāng)前所有的配置項(xiàng)
                // 接下來,在當(dāng)前dom下生成下拉選項(xiàng)的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>');
            });
        }
    });
    //默認(rèn)參數(shù)
    var defaluts = {
        container_class:'.container-options',   // 下拉選項(xiàng)容器class
        target_class:'.ajaxOptionThis',         // 當(dāng)前dom的標(biāo)識(shí)class 
        option_class:'.item',                   // 生成的下拉選項(xiàng)的class
        no_data_class:'.no-data',               // 無數(shù)據(jù)時(shí)對(duì)應(yīng)項(xiàng)的class
        no_data_msg:'未找到相關(guān)數(shù)據(jù)',              // 無數(shù)據(jù)時(shí)對(duì)應(yīng)項(xiàng)顯示的文字信息
         ajax_url:'******',                     // 請求的地址
        ajax_type:'get',                        // 請求的類型
        ajax_data:{                             // 請求的額外參數(shù)
            city : 'zg',
            page : 1
        },
        ajax_keyword_name:'kw',                 // 請求的關(guān)鍵詞的name值,value值固定為當(dāng)前文本框的值
    };
})(window.jQuery);

5.插件私有方法
有些時(shí)候,我們的插件需要一些私有方法,不能被外界訪問。

//私有方法,檢測用戶傳進(jìn)來的參數(shù)是否合法
function isValid(options) {
    return !options || (options && typeof options === "object") ? true : false;
}

6.公共方法 給別人來擴(kuò)展你的插件 或者 返回一些回調(diào)api

// 公共方法
// 當(dāng)點(diǎn)擊了選項(xiàng)后的回調(diào)函數(shù),$this為當(dāng)前輸入框,that為當(dāng)前點(diǎn)擊的選項(xiàng),opts為插件的配置項(xiàng)集合
$.fn.getAjaxOption.clickCallback = function ($this,that,opts) {}
// 當(dāng)ajax返回成功后執(zhí)行的回調(diào)函數(shù),$this為當(dāng)前輸入框,response為后端返回的數(shù)據(jù),opts為插件的配置項(xiàng)集合
$.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) {
            //檢測用戶傳進(jìn)來的參數(shù)是否合法
            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>');
                // 為當(dāng)前輸入框綁定 事件監(jiān)聽,動(dòng)態(tài)獲取值
                $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);
                        }
                    });
                })
                // 為下拉選項(xiàng)的每一項(xiàng)綁定click事件
                $(opts.container_class).on('click',opts.option_class,function(){
                    $.fn.getAjaxOption.clickCallback($this,this,opts);
                })
            });

        }
    });
    //默認(rèn)參數(shù)
    var defaluts = {
        // 容器dom
        container_class:'.container-options',
        target_class:'.ajaxOptionThis',
        option_class:'.item',
        no_data_class:'.no-data',
        no_data_msg:'未找到相關(guān)數(shù)據(jù)',
        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);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 不管你是前端程序員,還是后端程序員,無人不知JQuery,無人不曉JQuery。她的好處想必大家都知道,很多人喜歡...
    滇藏1987閱讀 1,257評(píng)論 0 9
  • jquery插件的開發(fā)包括兩種: 一種是類級(jí)別的插件開發(fā),即給jquery添加新的全局函數(shù),相當(dāng)于給jquery類...
    小豆soybean閱讀 776評(píng)論 0 4
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計(jì)者無需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性。 1....
    LaBaby_閱讀 1,503評(píng)論 0 2
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標(biāo)準(zhǔn)。 注意:講述HT...
    kismetajun閱讀 28,815評(píng)論 1 45
  • 重磅!國常會(huì)一錘定音 全面寬松基本確認(rèn)!(附解讀) 2018-07-24 11:13 券商中國 T大 剛剛召開的國...

友情鏈接更多精彩內(nèi)容