jQuery 插件開發——PopupLayer(彈出層)

  導讀:上次寫了一篇關於GridView的插件開發方法,上幾天因爲工做須要,花了一天左右的事件封裝了popupLayer(彈出層)插件。今天有時間就記錄一下本身的開發思想與你們分享下,同時也算是對這段時間的工做概要吧。css

  就我在開發過程當中的理解和開發的經驗,通常經常使用的彈出層有三類(其實還有一類就是彈出能夠輸入內容的,可是這種能夠被替代,因此就特別拿出來寫了):Confirm、Alert、LoadContent(url)。其中Alert又能夠分紅五種(固然也能夠是四種),分別是: "error"、"info"、"question"、"warning"、"alert" 。對於每一個名詞我就不一一介紹了,相信你們對這幾個名詞也都不陌生。若是實在瞭解,能夠看下easy ui中的說明。由於不少彈出插件就是相似這樣的命名,這樣既爲了便於他人理解,也便於和主流相一致吧(算是一種「規範」命名吧)。
html

  也扯不少了,下面開始真正的開發環節:ajax

  仍是我上次說過的,開發插件首先要對這個插件有必定的瞭解。知道它須要什麼樣的功能,是用來作什麼的。這也算是「需求分析」吧。雖然彈出層算是你們得常識吧,也要對其中的做用在進行一次邏輯分析。分析的好處在於你能夠提煉這些彈出層的異同點。說到這裏我想你們都瞭解了這是爲何了,對,就是要將共同點封裝起來。緩存

  這幾個彈出層的共同點不少,例如:彈出的樣式、彈出的位置、彈出的方式等等。。。這些均可以封裝起來。固然他們的不一樣點也很容易看出來,例如:加載的按鈕可能不同(Alert通常只有肯定按鈕,Confirm通常都是兩個按鈕,也能夠是一個)、警告的圖標不一樣等等。。。這些都是不一樣的地方。固然不一樣時相對的。咱們也是能夠進一個提煉的。app

  先說下開發步驟吧:ide

  第一步:「需求分析」,也就是我上面說的那些。肯定各類彈出層的異同點。oop

  第二步:封裝共同點測試

  第三步:特殊處理,也就是不一樣點的處理。(建議寫代碼的時候分開點,不要全部邏輯都寫到一塊兒)ui

  第四步:整合代碼,實現功能。(就是經過本身封裝的東西,得到想要的效果)this

  第五步:擴展性問題。這個是我最想強調的。不少人開發的眼光太太短淺(這裏不是特指誰,由於我之前也常犯這種問題),開發的插件(或是寫的代碼),不具備重用性。例如我開發這個的時候就出現了,插件開發完成了,單個測試都很好,沒問題。可是同時(或前後)彈出多個層就出問題了,這就是由於當時寫代碼時候,把一些變量寫的太死,致使不能夠擴展了。同時彈出來那個層的ID相同了。。。。。。這樣悲劇的事情想必不少人都會遇到,之前也用過私人寫的第三方插件出現相似的問題。其實出現這樣問題歸根究底仍是需求分析沒作好。

  第六步:測試。測試時很重要的環節,不少錯誤狀況都是測試出來的。因此不要吝惜那點測試的時間。好的插件(代碼)是測出來的。

  因爲篇幅受限只能貼出部分代碼以下:

(function () {

    //說明:alert彈出 五種狀態 "error"、"info"、"question"、"warning"、"alert"
    var popupEnumType = {
        Error: 1,
        Info: 2,
        Question: 3,
        Warning: 4,
        Alert: 5
    };

    //說明:顯示button的類型
    var popupEnumBtn = {
        SureAndCancel: 1,
        SureOnly: 2,
        CancelOnly: 3
    };

    var popupCommon = {
        //獲取 Confirm 基礎元素
        getBasicElements_Confirm: function (content, isShowIcon) {
            var htmlStr = "";
            htmlStr += "<div class='cancel_dingdai_tixing'> <dl class='f-oh'>";
            if (isShowIcon) {
                htmlStr += "<dd class='f-fl infoIcon'></dd>";
            }
            htmlStr += "<dd class='f-fl cancel_dingdai_text cancel_dingdai_text_content'>" + content + "</dd>" +
                       "     </dl>" +
                       " </div>";
            return htmlStr;
        },

        //獲取 Alert 基礎元素
        getBasicElements_Alert: function (popupType, content) {           
            var htmlStr = "";
            htmlStr += "<div class='cancel_dingdai_tixing'> <dl class='f-oh'>";
            htmlStr += "<dd class='f-fl ";
            switch (popupType) {
                case popupEnumType.Error:
                    htmlStr += "errorIcon";
                    break;
                case popupEnumType.Info:
                    htmlStr += "infoIcon";
                    break;
                case popupEnumType.Question:
                    htmlStr += "questionIcon";
                    break;
                case popupEnumType.Warning:
                    htmlStr += "warningIcon";
                    break;
                case popupEnumType.Alert:
                    htmlStr += "";
                    break;
            }
            htmlStr += "'></dd>";
            htmlStr += "         <dd class='f-fl cancel_dingdai_text cancel_dingdai_text_content'>" + content + "</dd>" +
                       "     </dl>" +
                       " </div>";
            return htmlStr;
        },

        //得到要顯示的彈出層
        getPopupLayerHtml: function (title, boxstyle, contentHtml, popupBtnType, btnSureText, btnCancelText) {

            var htmlStr = "";
            htmlStr += "<div id='" + this.returnId("popupBg") + "' userDefinedAttr='popupLayerBg' class='popupBg'

            style='z-index:" + this.returnPopupBgZIndex() + "' ></div>";
            htmlStr +=  "<div id='" + this.returnId("popupShow") + "' class='popupShow' "+

            "   style='z-index:" + this.returnPopupShowZIndex() + "'>" +
                         "   <div class='cancel_dingdai_pop'>" +
                         "       <div class='cancel_dingdai_wrap_out' id='" + this.returnId("wrapOut") + "'>" +
                         "           <div id='popupBox' class='cancel_dingdai_wrap " + boxstyle + "' >" +
                         "               <h2 class='cancel_dingdai_title f-oh'>" +
                         "                   <span class='cancel_dingdai_text f-fl'>" + title + "</span>" +
                         "                   <em id='" + this.returnId("cancelImg") + "' class='cancel_dingdai_title_icon f-fr'>"+

            "         </em>" +
                         "               </h2>" +
                         "               <div id='" + this.returnId("popupContent") + "' style='width:100%;height:auto;"+

            "            background-color:white'>";
            htmlStr +=         contentHtml;
            htmlStr += "               </div>";
            htmlStr +=       this.getPopupLayerBtn(popupBtnType, btnSureText, btnCancelText);
            htmlStr += "           </div>" +
                         "       </div>" +
                         "    </div>" +
                         "</div>";
            return htmlStr;
        },
        //彈出層按鈕選擇
        getPopupLayerBtn: function (popupBtnType, btnSureText, btnCancelText) {
            btnSureText = this.getParam(btnSureText) == "" ? "肯定" : btnSureText;
            btnCancelText = this.getParam(btnCancelText) == "" ? "取消" : btnCancelText;
            var htmlStr = "";
            htmlStr += "<div class='cancel_dingdai_tijiao'>" +
                          "    <dl class='f-fr f-oh'>";
            var sureBtnStr = "<dd class='f-fl cancel_dingdai_submit'>" +
                             "    <input type='button' id='" + this.returnId("popupBtnSure") +

           "  '  value='" + btnSureText + "' />" +
                             "</dd>";
            var cancelBtnStr = "<dd class='f-fl cancel_dingdai_cancel'>" +
                             "    <input type='button' id='" + this.returnId("popupBtnCancel") +

           "  ' value='" + btnCancelText + "' />" +
                             "</dd>";
            switch (popupBtnType) {
                case popupEnumBtn.SureAndCancel:
                    htmlStr += sureBtnStr + cancelBtnStr;
                    break;
                case popupEnumBtn.SureOnly:
                    htmlStr += sureBtnStr;
                    break;
                case popupEnumBtn.CancelOnly:
                    htmlStr += cancelBtnStr;
                    break;
            }

            htmlStr += "    </dl>" +
                          "</div>";
            return htmlStr;
        },
        //判斷元素是否存在,存在後部分加1
        returnId: function (prefix) {
            var len = $("div[userDefinedAttr='popupLayerBg']").length;
            if (len < 0) {
                return prefix + "_1";
            }
            len++;
            return prefix + "_" + len;
        },
        returnPopupBgZIndex: function () {
            var len = $("div[userDefinedAttr='popupLayerBg']").length;
            if (len < 0) {
                return 1001;
            }
            return 1002 + 2 * len - 1;
        },
        returnPopupShowZIndex: function () {
            var len = $("div[userDefinedAttr='popupLayerBg']").length;
            if (len < 0) {
                return 1002;
            }
            return 1002 + 2 * len;
        },
        //顯示彈出層
        showPopup: function () {
            var len = $("div[userDefinedAttr='popupLayerBg']").length;
            $("#popupBg_" + len).show();
            $("#popupBg_" + len).css("height", $(document).height());
            $("#popupShow_" + len).show();
        },
        //關閉彈出層
        closePopup: function () {
            var len = $("div[userDefinedAttr='popupLayerBg']").length;
            $("#popupBg_" + len).hide();
            $("#popupShow_" + len).hide();
            $("#popupBg_" + len).remove();
            $("#popupShow_" + len).remove();
        },
        //註冊基礎事件
        registerBasicEvent: function () {
            //「X」號圖標和取消按鈕
            var len = $("div[userDefinedAttr='popupLayerBg']").length;
            $("#cancelImg_" + len + ",#popupBtnCancel_" + len).click(function () {
                popupCommon.closePopup();
            });
        },
        getParam: function (param) {
            if (typeof (param) == "undefined") {
                return "";
            } else {
                return param;
            }
        },
        popupLayerPosition: function () {
            var len = $("div[userDefinedAttr='popupLayerBg']").length;
            var objHeight = $("#wrapOut_" + len).height() / 2;
            var topValue = $(window).height() / 2 - objHeight + "px";
            $("#wrapOut_" + len).css("margin-top", topValue);
        },

        coverObject: function (obj1, obj2) {
            var o = this.cloneObject(obj1, false);
            var name;
            for (name in obj2) {
                if (obj2.hasOwnProperty(name)) {
                    o[name] = obj2[name];
                }
            }
            return o;
        },

        cloneObject: function (obj, deep) {
            if (obj === null) {
                return null;
            }
            var con = new obj.constructor();
            var name;
            for (name in obj) {
                if (!deep) {
                    con[name] = obj[name];
                } else {
                    if (typeof (obj[name]) == "object") {
                        con[name] = $.cloneObject(obj[name], deep);
                    } else {
                        con[name] = obj[name];
                    }
                }
            }
            return con;
        }
    };

    /************************(彈出層:加載url)*************************/

    var popupLoad = function () {
        this.defaultParams = {
            //參數定義
            title: "",
            boxstyle: "",
            url: "",
            data: "",
            loadback: $.noop,
            callback: $.noop,//注意:返回值要是true/false的方法
            btnId: "",
            btnSureText: "",
            btnCancelText: ""
        };
        this.options = {};
        this.popupLength = 0;
    };

    popupLoad.prototype = {
        constructor: popupLoad,
        init: function (params) {
            this.options = popupCommon.coverObject(this.defaultParams, params);
            this._init(this.options);
        },

        _init: function (options) {
            var popupLay = popupCommon.getPopupLayerHtml(this.options.title, this.options.boxstyle, "",

            popupEnumBtn.SureAndCancel, this.options.btnSureText, this.options.btnCancelText);
            $("body").append(popupLay);
            $("#" + options.btnId).attr("disabled", "disabled");//防止屢次發送請求
            $.ajaxSetup({
                cache: false //關閉 AJAX 緩存
            });
            this.popupLength = $("div[userDefinedAttr='popupLayerBg']").length;
            $("#popupContent_" + this.popupLength).load(options.url, options.data, function () {
                popupCommon.showPopup();
                popupCommon.popupLayerPosition();
                $("#" + options.btnId).removeAttr("disabled");
                if ($.isFunction(options.loadback)) {
                    options.loadback();
                }
            });
            popupCommon.registerBasicEvent();
            this._registerBtnClick(options);
        },
        _registerBtnClick: function (options) {
            var len = this.popupLength;
            $("#popupBtnSure_" + len).click(function () {
                if (!$.isFunction(options.callback)) {
                    return;
                }
                if (!options.callback()) {
                    return;
                }
                popupCommon.closePopup();
            });
        }
    };

    $.popupLoad = new popupLoad();

    /************************(彈出層:confirm框)*************************/

    var popupConfirm = function () {
        //參數定義
        this.defaultParams = {
            //參數定義
            title: "",
            content: "",
            boxstyle: "",
            isShowIcon: true,
            callback: $.noop,//注意:返回值要是true/false的方法
            btnSureText: "",
            btnCancelText: ""
        };
        this.options = {};
        this.popupLength = 0;
    };

    popupConfirm.prototype = {
        constructor: popupConfirm,
        init: function (params) {
            this.options = popupCommon.coverObject(this.defaultParams, params);
            this._init(this.options);
        },
        _init: function (options) {
            var contentHtml = popupCommon.getBasicElements_Confirm(this.options.content, this.options.isShowIcon);
            var popupLay = popupCommon.getPopupLayerHtml(this.options.title, this.options.boxstyle, contentHtml,

              popupEnumBtn.SureAndCancel, this.options.btnSureText, this.options.btnCancelText);
            $("body").append(popupLay);
            this.popupLength = $("div[userDefinedAttr='popupLayerBg']").length;
            popupCommon.showPopup();
            popupCommon.registerBasicEvent();
            popupCommon.popupLayerPosition();
            this._registerBtnClick(options);
        },
        _registerBtnClick: function (options) {
            var len = this.popupLength;
            $("#popupBtnSure_" + len).click(function () {
                popupCommon.closePopup();
                if ($.isFunction(options.callback)) {
                    options.callback();
                }
            });
        }
    };
    $.popupConfirm = new popupConfirm();

    /************************(彈出層:Alert框)*************************/

    var popupAlert = function (popupType) {
        //參數定義
        this.defaultParams = {
            title: "",
            content: "",
            boxstyle: "",
            callback: $.noop,//注意:返回值要是true/false的方法
        };
        this.options = {};
        this.popupLength = 0;
        this.popupType = popupType;
    };
    popupAlert.prototype = {
        constructor: popupAlert,
        init: function (params) {
            this.options = popupCommon.coverObject(this.defaultParams, params);
            this._init(this.options);
        },
        _init: function (options) {
            var contentHtml = popupCommon.getBasicElements_Alert(this.popupType, this.options.content);
            var popupLay = popupCommon.getPopupLayerHtml(this.options.title, this.options.boxstyle,

              contentHtml, popupEnumBtn.SureOnly);
            $("body").append(popupLay);
            this.popupLength = $("div[userDefinedAttr='popupLayerBg']").length;
            popupCommon.showPopup();
            popupCommon.registerBasicEvent();
            popupCommon.popupLayerPosition();
            this._registerBtnClick(options);
        },
        _registerBtnClick: function (options) {
            var len = this.popupLength;
            $("#popupBtnSure_" + len).click(function () {
                popupCommon.closePopup();
                if ($.isFunction(options.callback)) {
                    options.callback();
                }
            });
        }
    };
    $.popupError = new popupAlert(popupEnumType.Error);
    $.popupInfo = new popupAlert(popupEnumType.Info);
    $.popupQuestion = new popupAlert(popupEnumType.Question);
    $.popupWarning = new popupAlert(popupEnumType.Warning);
    $.popupAlert = new popupAlert(popupEnumType.Alert);
})(jQuery);

  總結:因爲篇幅太長css樣式就不貼了,若是有須要或者想共同探討的同仁,隨時聯繫我,QQ:296319075  同時也但願你們提出寶貴意見,不吝賜教。共同進步!若有轉載,請註明出處,謝謝!^_^

相關文章
相關標籤/搜索