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='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 同时也希望大家提出宝贵意见,不吝赐教。共同进步!如有转载,请注明出处,谢谢!^_^
jQuery 插件开发——PopupLayer(弹出层)的更多相关文章
- jquery鼠标经过弹出层写法
jquery鼠标经过弹出层写法<pre><div class="navitem"><a href="/index.php?c=news&am ...
- jQuery点击弹出层,弹出模态框,点击模态框消失
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- 一款基于jQuery的漂亮弹出层
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- jquery 点击弹出层自身以外的任意位置,关闭弹出层
<!--弹出层---> <div class="mask"> <div class="wrap"></div&g ...
- jQuery Layer mobile 弹出层
layer mobile是为移动设备(手机.平板等webkit内核浏览器/webview)量身定做的弹层支撑,采用Native JavaScript编写,完全独立于PC版的layer,您需要按照场景选 ...
- jQuery拖拽 & 弹出层
了解更多请查看 官网 和 API iDrag & iDialog 介绍 特点: iDialog.js依赖于jquery编写的简单易用的对话框,同时还可以通过添加css3,改变对话框的展现动画. ...
- JQuery弹出层,点击按钮后弹出遮罩层,有关闭按钮【转】
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...
- query简洁弹出层代码
<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content=&q ...
- Jquery 点击图片在弹出层显示大图
http://blog.csdn.net/wongwaidah/article/details/28432427(案例链接出处,本人只是转载收藏) <html> <head> ...
随机推荐
- java 连接oracle数据库
package shujuku; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepared ...
- CF 986A Fair——多源bfs
题目:http://codeforces.com/contest/986/problem/A 如果从每个村庄开始bfs找货物,会超时. 发现k较小.那就从货物开始bfs,给村庄赋上dis[ 该货物 ] ...
- CentOS7中配置基于Nginx+Supervisor+Gunicorn的Flask项目
配置Nginx 1.安装nginx yum install nginx 2.安装好后在/etc/nginx/default.d中添加location的配置,并指向8001端口,以后Gunicorn会监 ...
- walle代码发布系统配置
walle Walle 一个web部署系统工具,配置简单.功能完善.界面流畅.开箱即用! 支持git.svn版本管理,支持各种web代码发布, PHP,Python,JAVA等代码的发布.回滚,可以通 ...
- UITableView常见用法以及注意细节
UITableView用途广泛,而且多样化,其中有一些不太常用,用到的话需要去查资料,今天边用边记录下来 *第一发:UITableViewCell 分割线 1. 分割线样式 [self.tableVi ...
- @property_@synthesize 配套使用
@property 类默认实现变量的get set方法 @synthesize 是指定那个变量的 get和set方法 eg: .h文件中定义 类Student中含有两个 int age,和int _a ...
- 一文读懂非关系型数据库(NoSQL)
为了更好的理解非关系型数据库,我又深入的度娘了下 原文地址:https://baijiahao.baidu.com/po/feed/share?wfr=spider&for=pc&co ...
- urllib2模块中文翻译与学习 - Python 2.7.8官方文档
总结 目的 打开指定网址 要求 了解需要处理的网站的操作流程 数据包的构造与提交 对可能的响应处理选择合适的处理器(模块内的各种 *Handler()) 核心 urllib.urlencode(que ...
- springmvc----demo1---hello---bai
import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import ...
- Python打造一个目录扫描工具
目标:用Python3写一款小型的web目录扫描工具 功能:1.扫描指定站点 2.指定网站脚本类型来扫描 3.可控线程 4.可保存扫描结果 首先定义一个命令参数的函数 def parse_option ...