1. 程式人生 > >JS元件系列——封裝自己的JS元件,你也可以

JS元件系列——封裝自己的JS元件,你也可以

前言:之前分享了那麼多bootstrap元件的使用經驗,這篇博主打算研究下JS元件的擴充套件和封裝,我們來感受下JQuery為我們提供$.Extend的神奇,看看我們怎麼自定義自己的元件,比如我們想擴充套件一個$("#id").MyJsControl({})做我們自己的元件,我們該如何去做呢,別急,我們慢慢來看看過程。

一、擴充套件已經存在的元件

1、需求背景

很多時候,我們使用jquery.ajax的方式向後臺傳送請求,型如

      $.ajax({
                type: "post",
                url: "/User/Edit",
                data: { data: JSON.stringify(postdata) },
                success: 
function (data, status) { if (status == "success") { toastr.success('提交資料成功'); $("#tb_aaa").bootstrapTable('refresh'); } }, error: function (e) { }, complete:
function () { } });

這種程式碼太常見了,這個時候我們有這樣一個需求:在自己呼叫ajax請求的時候,我們不想每次都寫error:function(e){}這種程式碼,但是我們又想讓它每次都將ajax的錯誤資訊輸出到瀏覽器讓使用者能夠看到。怎麼辦呢?

2、實現原理

要想實現以上效果其實並不難,我們可以將$.ajax({})封裝一層,在封裝的公共方法裡面定義error對應的事件即可。確實,這樣能達到我們的要求,但是並不完美,原因很簡單:1)在jquery的基礎上面再封裝一層,效率不夠高;2)需要改變呼叫者的習慣,每次呼叫ajax的時候需要按照我們定義的方法的規則來寫,而不能直接用原生的$.ajax({})這種寫法,這是我們不太想看到。

既然如此,那我們如何做到既不封裝控制元件,又能達到以上要求呢?答案就是通過我們的$.extend去擴充套件原生的jquery.ajax

其實實現起來也並不難,通過以下一段程式碼就能達到我們的要求。

(function ($) {
    //1.得到$.ajax的物件
    var _ajax = $.ajax;
    $.ajax = function (options) {
        //2.每次呼叫傳送ajax請求的時候定義預設的error處理方法
        var fn = {
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                toastr.error(XMLHttpRequest.responseText, '錯誤訊息', { closeButton: true, timeOut: 0, positionClass: 'toast-top-full-width' });
            },
            success: function (data, textStatus) { },
            beforeSend: function (XHR) { },
            complete: function (XHR, TS) { }
        }
        //3.如果在呼叫的時候寫了error的處理方法,就不用預設的
        if (options.error) {
            fn.error = options.error;
        }
        if (options.success) {
            fn.success = options.success;
        }
        if (options.beforeSend) {
            fn.beforeSend = options.beforeSend;
        }
        if (options.complete) {
            fn.complete = options.complete;
        }
        //4.擴充套件原生的$.ajax方法,返回最新的引數
        var _options = $.extend(options, {
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                fn.error(XMLHttpRequest, textStatus, errorThrown);
            },
            success: function (data, textStatus) {
                fn.success(data, textStatus);
            },
            beforeSend: function (XHR) {
                fn.beforeSend(XHR);
            },
            complete: function (XHR, TS) {
                fn.complete(XHR, TS);
            }
        });
        //5.將最新的引數傳回ajax物件
        _ajax(_options);
    };
})(jQuery);

如果沒接觸過jquery裡面$.extend這個方法的童鞋可能看不懂以上是什麼意思。好,我們首先來看看jquery API對$.extend()方法是作何解釋的。

什麼意思呢?我們來看官方的兩個例子就知道了

栗子一:

var settings = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
$.extend(settings, options);

結果:

settings == { validate: true, limit: 5, name: "bar" }

栗子二:

var empty = {};
var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
var settings = $.extend(empty, defaults, options);

結果:

settings == { validate: true, limit: 5, name: "bar" }
empty == { validate: true, limit: 5, name: "bar" }

以上的兩個簡單例子就說明extend()方法作用就是合併另個物件,有相同的則覆蓋,沒有相同的則新增。就是這麼簡單。

瞭解了$.extend()的作用,我們就能大概看懂上面那個擴充套件jquery.ajax的實現了吧。主要的步驟分為:

1)定義預設的error處理方法。

var fn = {
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                toastr.error(XMLHttpRequest.responseText, '錯誤訊息', { closeButton: true, timeOut: 0, positionClass: 'toast-top-full-width' });
            },
            success: function (data, textStatus) { },
            beforeSend: function (XHR) { },
            complete: function (XHR, TS) { }
        }

2)判斷使用者在呼叫$.ajax({})的時候是否自定了error:function(){},如果定義過,則使用使用者定義的,反之則用預設的error處理方法。

3)使用$.extend()將error預設處理方法傳入$.ajax()的引數中。我們看options引數時包含$.ajax()方法裡面所有的引數的,然後用預設的fn去擴充套件它即可。

通過以上三步就能夠實現對$.ajax()方法裡面error預設處理方法。這樣擴充套件,對於我們使用者來說完全感覺不到變化,我們仍然可以$.ajax({});這樣去傳送ajax請求,如果沒有特殊情況,不用寫error處理方法。

3、元件擴充套件的意義

使用元件擴充套件,能夠幫助我們在原有元件上面增加一些和我們系統業務相關的處理需求,而在使用時,還是和使用原生元件一樣去呼叫,免去了在元件上面再封裝一層的臃腫。

二、擴充套件自己元件

上面通過$.extend()方法擴充套件了$.ajax()的error事件處理方法。下面我們來封裝一個自己的元件試試,功能很簡單,但比較有說明性。我們就以select這個元件為例,很多情況下,我們的select裡面的option都是需要從資料庫裡面取資料的,所以一般的做法就是傳送一個ajax請求,然後在success方法裡面拼html。現在我們就封裝一個select遠端取資料的方法。

1、程式碼實現以及使用示例

先上乾貨吧,將寫好的整出來:

(function ($) {
     //1.定義jquery的擴充套件方法combobox
    $.fn.combobox = function (options, param) {
        if (typeof options == 'string') {
            return $.fn.combobox.methods[options](this, param);
        }
        //2.將呼叫時候傳過來的引數和default引數合併
        options = $.extend({}, $.fn.combobox.defaults, options || {});
        //3.新增預設值
        var target = $(this);
        target.attr('valuefield', options.valueField);
        target.attr('textfield', options.textField);
        target.empty();
        var option = $('<option></option>');
        option.attr('value', '');
        option.text(options.placeholder);
        target.append(option);
        //4.判斷使用者傳過來的引數列表裡面是否包含資料data資料集,如果包含,不用發ajax從後臺取,否則否送ajax從後臺取資料
        if (options.data) {
            init(target, options.data);
        }
        else {
            //var param = {};
            options.onBeforeLoad.call(target, options.param);
            if (!options.url) return;
            $.getJSON(options.url, options.param, function (data) {
                init(target, data);
            });
        }
        function init(target, data) {
            $.each(data, function (i, item) {
                var option = $('<option></option>');
                option.attr('value', item[options.valueField]);
                option.text(item[options.textField]);
                target.append(option);
            });
            options.onLoadSuccess.call(target);
        }
        target.unbind("change");
        target.on("change", function (e) {
            if (options.onChange)
                return options.onChange(target.val());
        });
    }

    //5.如果傳過來的是字串,代表呼叫方法。
    $.fn.combobox.methods = {
        getValue: function (jq) {
            return jq.val();
        },
        setValue: function (jq, param) {
            jq.val(param);
        },
        load: function (jq, url) {
            $.getJSON(url, function (data) {
                jq.empty();
                var option = $('<option></option>');
                option.attr('value', '');
                option.text('請選擇');
                jq.append(option);
                $.each(data, function (i, item) {
                    var option = $('<option></option>');
                    option.attr('value', item[jq.attr('valuefield')]);
                    option.text(item[jq.attr('textfield')]);
                    jq.append(option);
                });
            });
        }
    };

    //6.預設引數列表
    $.fn.combobox.defaults = {
        url: null,
        param: null,
        data: null,
        valueField: 'value',
        textField: 'text',
        placeholder: '請選擇',
        onBeforeLoad: function (param) { },
        onLoadSuccess: function () { },
        onChange: function (value) { }
    };
})(jQuery);

先來看看我們自定義元件如何使用:

用法一:通過URL遠端取資料並初始化

首先定義一個空的select 

<select id="sel_search_plant" class="form-control"></select>

然後初始化它

$(function(){
     $('#sel_search_plant').combobox({
            url: '/apiaction/Plant/Find',
            valueField: 'TM_PLANT_ID',
            textField: 'NAME_C'
      });
})

引數很簡單,就不一一介紹了。很簡單有木有~~

用法二:取值和設定

var strSelectedValue = $('#sel_search_plant').combobox("getValue");
$('#sel_search_plant').combobox("setValue", "aaa");

其實對於簡單的select標籤,博主覺得這裡的getValu和SetValue意義不大,因為直接通過$('#sel_search_plant').val()就能解決的事,何必要再封一層。這裡僅僅是做演示,試想,如果是封裝成類似select2或者multiselect這種元件,getValue和setValue的意義就有了,你覺得呢?

2、程式碼詳細講解

上面的實現程式碼,如果您一眼就能看懂,證明您是經常封元件的大蝦了,下面的就不用看了。如果看不懂,也沒關係,我們將程式碼拆開詳細看看裡面是什麼鬼。

(1)首先看看我們最常看到的如下寫法:

(function ($) {
      //....封裝元件邏輯
})(jQuery);

初初看到這種用法,博主也是狂抓,這是什麼鬼嘛,四不像啊。使用多了之後才知道原來這就是一個匿名函式的形式。將它拆開來看如下:

var fn = function($){
       //.....元件封裝邏輯
};
fn(jQuery);

也就是說這種寫法就表示先定義一個方法,然後立即呼叫這個方法,jQuery相當於實參。開啟jquery.js的原檔案可以看到,jQuery是這個檔案裡面的一個全域性變數。

(2)定義自己的元件的程式碼:

$.fn.combobox = function (options, param) {
    
};

習慣這種寫法的應該知道,這個就表示向jquery物件新增自定義方法,比如你想使用文章開始的 $("#id").MyJsControl({}) 這種用法,你就可以這樣定義 $.fn.MyJsControl=function(options){} 。

(3) options = $.extend({}, $.fn.combobox.defaults, options || {}); 這一句,看過上文的朋友應該還記得extend這麼一個方法吧,怎麼樣,又來了你。這句話其實就沒什麼好說的了,合併預設引數和使用者傳進來的引數。

(4)預設引數列表

 $.fn.combobox.defaults = {
        url: null,
        param: null,
        data: null,
        valueField: 'value',
        textField: 'text',
        placeholder: '請選擇',
        onBeforeLoad: function (param) { },
        onLoadSuccess: function () { },
        onChange: function (value) { }
    };

如果使用者沒有傳參,就用預設的引數列表。如果你夠細心,你會發現博主之前分享的其他bootstrap元件的js檔案裡面都有這麼一個default引數列表。我們隨便找兩個:

bootstrap上傳元件

bootstrap table元件

基本都是這麼些用法。這樣來看,是否也可以自己封一個js元件~~

三、總結

以上就是博主對js元件擴充套件以及封裝用法的認識和總結。當然,都是些比較簡單基礎的封裝,如果想要實現類似bootstrap table的元件,那還差得很遠。不過萬丈高樓平地起,只要打好基礎,封一個自己的table元件也不是什麼大問題。文中如果有理解不對的地方,歡迎指出,博主將不勝感激。如果本文能夠對你有絲毫幫助,麻煩擡起你的小手點個推薦,博主一定繼續努力,將更好的文章分享給大家。

相關推薦

JS元件系列——封裝自己JS元件可以

前言:之前分享了那麼多bootstrap元件的使用經驗,這篇博主打算研究下JS元件的擴充套件和封裝,我們來感受下JQuery為我們提供$.Extend的神奇,看看我們怎麼自定義自己的元件,比如我們想擴充套件一個$("#id").MyJsControl({})做我們自己的元件,我們該如何去做呢,別急,我們慢慢來

JS元件系列——分享自己封裝的Bootstrap樹形元件:jqTree

 前言:之前的一篇介紹了下如何封裝自己的元件,這篇再次來體驗下自己封裝元件的樂趣。看過博主部落格的園友應該記得之前分享過一篇樹形選單的使用JS元件系列——Bootstrap 樹控制元件使用經驗分享,這篇裡面第一個Jquery Tree,只是用簡單樣式和js去實現了效果,沒有給出一個系統的封裝,這篇博主就來試試

JS組件系列——封裝自己JS組件

style throw function check 信息 timeout 進行 var trigge 1、需求背景   很多時候,我們使用jquery.ajax的方式向後臺發送請求,型如 $.ajax({ type: "post", url: "/Use

JS元件系列——Bootstrap 樹控制元件使用經驗分享

前言:很多時候我們在專案中需要用到樹,有些樹僅僅是展示層級關係,有些樹是為了展示和編輯層級關係,還有些樹是為了選中項然後其他地方呼叫選中項。不管怎麼樣,樹控制元件都是很多專案裡面不可或缺的元件之一。今天,博主打算結合自己的使用經歷和網上找到的一些不錯的樹控制元件在這裡做一個分享,希望能幫大家找到最合適的控制元

JS元件系列——開源免費圖表元件:Chart.js

前言:最近被開源免費得有點上火了,各種元件首先想到的就是是開源否、是否免費、是否和bootstrap風格一致。想著以後做報表肯定要用到圖表元件的,於是在Bootstrap中文網上面找到了Chart.js,總的來說,這個元件不能說最好,但是對於一般不太複雜的報表是夠用了。今天就來看看它如何使用吧。 一、元件比

原生js---ajax的封裝外掛.js---(對get和post做了相容)

function ajax(method,url,data,fn){ // 1、建立物件 var xhr=null; try{ xhr=new XMLHttpRequest(); }catch(e){ xhr=new ActiveXObject("Micr

Java(1) Java中如何使封裝自己的類建立並使用自己的類庫?

Java中如何使封裝自己的類,建立並使用自己的類庫?            ——感謝您的閱讀,本篇文章轉載自以下連結,支援原創,人人有責。 http://blog.csdn.net/luoweifu/ar

Java中如何使封裝自己的類建立並使用自己的類庫?

Java中如何使封裝自己的類,建立並使用自己的類庫? 該文轉載SmilingSunrise的文章:http://blog.csdn.net/luoweifu/article/details/7281494 一、先來明白一下關於classpath和path的概念 p

Java中如何封裝自己的類建立並使用自己的類庫?

Java中如何使封裝自己的類,建立並使用自己的類庫?  ——感謝您的閱讀,轉載請標明出處! 隨著自己的程式設計經歷的積累會發現往往自己在一些專案中寫的類在別的專案中也會有多次用到。你肯定會想:如何自己的寫的一些常用的類積累起來,生成自己的類庫?如果是這樣的話,很慶幸,

補習系列(9)-springboot 定時器用對了嗎

empty cront apps 任務並發 轉發 gis execute 大小 定義 目錄 簡介 一、應用啟動任務 二、JDK 自帶調度線程池 三、@Scheduled 定制 @Scheduled 線程池 四、@Async 定制 @Async 線程池 小結 簡介 大

找到自己的伯樂就是一匹黑馬。

逝者如斯夫,不捨晝夜。轉眼已經來到黑馬一個月,一個月的基礎班,讓我慢慢的適應了這種學習生活,在這匆忙而又充實的一個月最大的感受就是,時間永遠不夠用,它就像長了腳的妖怪跑得飛快,只有去抓住它,它似乎才會停下腳步,你就可以幹自己想幹的事。    先說說為什麼來到了黑馬吧,由於自己

之前的部落格雖然是自己寫的但是得經常回顧啊。

之前的部落格雖然是自己寫的,但是也得經常回顧啊。 剛才用到執行緒鎖,但是又不敢確定用什麼最好了。之前學習過,但使用不多,不夠深刻,也沒有很理解,有點遺忘了。 ReentrantLock 和Synchronized都是可重入鎖,即本執行緒擁有鎖以後可以再次執行進入鎖所相關的程式碼而不會阻塞,只是count+

八年Java程式設計師分享自己學習規劃該如何選擇自己的學習路線!

Java程式設計師你是否有了明確的職業發展規劃? 就現在經濟大環境而言,很不樂觀,Java程式設計師的日子也很不好過,無論是還在找工作的、還是已經入職多年、哪怕做到專案經理技術經理的,壓力都異常巨大,似乎處處充滿危機。但是,仔細分析一下,出路還是有的,甚至解決溫飽、過上有房有車沒貸款的生活也是很

如果當了老闆老闆幹什麼?——不把自己當老闆永遠都混不好

  今天晚上一來京出差的老哥們找我喝酒。詢問近況,他抱怨了很多無奈,滿滿都是負能量——工作興趣不大,老闆也不好伺候,想跳槽卻沒好去處;同部門一個資歷差不多的傢伙沒什麼真水平,就是會來事兒能巴結,最近人家剛被提拔;和女友辛苦攢錢湊首付中,本來就過得緊巴巴的。但一想到未來還有房貸、小孩、身體都不是太好的父母老人

不把自己當老闆永遠都混不好

轉水木社群,心態上換位思考 今天晚上一來京出差的老哥們找我喝酒。詢問近況,他抱怨了很多無奈,滿滿都是負 能量——工作興趣不大,老闆也不好伺候,想跳槽卻沒好去處;同部門一個資歷差不多的 傢伙沒什麼真水平,就是會來事兒能巴結,最近人家剛被提拔;和女友辛苦攢錢湊首付中 ,本來就

封裝的加密演算法不懂

function Base64() { // private property _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; // publi

一天就可以擁有自己的論壇心動了嗎?

服務器 私有雲 天涯社區 數據 節點 實操 你是 技術分享 e30 你是虎撲JRS嗎?你上過知乎嗎?你逛過天涯社區嗎?我相信絕大多數的人都逛過論壇。論壇是一個很好玩的東西,聚集了誌同道合的人們。但是你有沒有想過自己搭建一個論壇?可以搭建一個自己興趣領域的論壇,吸引人們一起來

【10000+文章匯總】技巧都在這裏了能寫出1w+好文!

51cto博客 10000+ 自 #我要10000+# 計劃啟動以來,已經有多位作者參與其中,我們通過文章專屬推廣渠道,取得了驚人的效果!單篇文章的閱讀量,最高達到55倍的閱讀量增長。從默默無聞,到有人喜歡,獲得關註的同時,打造個人影響力。現在讓我們來看看,這些 10000+ 好文,都有哪些~標題閱讀

做到這一點可以成為優秀的程序員

page 需要 技術學 好的 事情 高級 搜索引擎 的確 else 作為一個程序員,我經常會問自己一個問題: 優秀的程序員都具備哪些特質? 我總結過很多特質,例如: 有解決問題的能力 有獨立思考的能力 有好奇心、有探索精神 邏輯清晰,能夠用通俗的語言把技

我不是一名UX設計師不是

交互設計 以下內容由Mockplus團隊翻譯整理,僅供學習交流,Mockplus是更快更簡單的原型設計工具。 最近幾年,用戶體驗這個術語開始出現。而且隨著它的發展,我們也見證了用戶體驗設計師的崛起。 每隔幾個月,就會有人在twitter上曬