zoukankan      html  css  js  c++  java
  • jQuery 插件开发——PopupLayer(弹出层)

      导读:上次写了一篇关于GridView的插件开发方法,上几天由于工作需要,花了一天左右的事件封装了popupLayer(弹出层)插件。今天有时间就记录一下自己的开发思想与大家分享下,同时也算是对这段时间的工作概要吧。

      就我在开发过程中的理解和开发的经验,一般常用的弹出层有三类(其实还有一类就是弹出可以输入内容的,但是这种可以被替代,所以就特别拿出来写了):Confirm、Alert、LoadContent(url)。其中Alert又可以分成五种(当然也可以是四种),分别是: "error"、"info"、"question"、"warning"、"alert" 。对于每个名词我就不一一介绍了,相信大家对这几个名词也都不陌生。如果实在了解,可以看下easy ui中的说明。因为很多弹出插件就是类似这样的命名,这样既为了便于他人理解,也便于和主流相一致吧(算是一种“规范”命名吧)。

      也扯很多了,下面开始真正的开发环节:

      还是我上次说过的,开发插件首先要对这个插件有一定的了解。知道它需要什么样的功能,是用来做什么的。这也算是“需求分析”吧。虽然弹出层算是大家得常识吧,也要对其中的作用在进行一次逻辑分析。分析的好处在于你可以提炼这些弹出层的异同点。说到这里我想大家都了解了这是为什么了,对,就是要将共同点封装起来。

      这几个弹出层的共同点很多,例如:弹出的样式、弹出的位置、弹出的方式等等。。。这些都可以封装起来。当然他们的不同点也很容易看出来,例如:加载的按钮可能不一样(Alert一般只有确定按钮,Confirm一般都是两个按钮,也可以是一个)、警告的图标不同等等。。。这些都是不同的地方。当然不同时相对的。我们也是可以进一个提炼的。

      先说下开发步骤吧:

      第一步:“需求分析”,也就是我上面说的那些。确定各种弹出层的异同点。

      第二步:封装共同点

      第三步:特殊处理,也就是不同点的处理。(建议写代码的时候分开点,不要所有逻辑都写到一起)

      第四步:整合代码,实现功能。(就是通过自己封装的东西,获得想要的效果)

      第五步:扩展性问题。这个是我最想强调的。很多人开发的眼光太过短浅(这里不是特指谁,因为我以前也常犯这种问题),开发的插件(或是写的代码),不具有重用性。例如我开发这个的时候就出现了,插件开发完成了,单个测试都很好,没问题。但是同时(或先后)弹出多个层就出问题了,这就是因为当时写代码时候,把一些变量写的太死,导致不可以扩展了。同时弹出来那个层的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='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  同时也希望大家提出宝贵意见,不吝赐教。共同进步!如有转载,请注明出处,谢谢!^_^

  • 相关阅读:
    hdu 4614 线段树 二分
    cf 1066d 思维 二分
    lca 最大生成树 逆向思维 2018 徐州赛区网络预赛j
    rmq学习
    hdu 5692 dfs序 线段树
    dfs序介绍
    poj 3321 dfs序 树状数组 前向星
    cf 1060d 思维贪心
    【PAT甲级】1126 Eulerian Path (25分)
    【PAT甲级】1125 Chain the Ropes (25分)
  • 原文地址:https://www.cnblogs.com/mzws/p/3804417.html
Copyright © 2011-2022 走看看