自定义javascript弹窗

当前我们可以通过浏览器自带的alert,prompt弹框来提示用户或取得用户输入信息。


此二种方式具有的缺陷:

1. 阻塞:即JS执行至alert, prompt方法时待用户操作后再进行下一个语句的执行。即同步操作

2. 样式单一: 针对同一种浏览器,其弹框样式固定,不够美观。


下面我们通过自定义一个弹框库(js),来解决上面二个问题。

目标:

1. 用户只需使用定义好的js库即可使用弹框。

2. 弹框具有“确定”或“取消”功能,并可回调用户注册的函数(即单击确定或取消后回调的函数)

3. 用户如果想修改样式可自定义css


思路:

1. 弹框以普通html元素来实现, 弹框具有背景(overlay)以遮盖其余部分,防止用户操作弹框以外的页面部分。

2. 框体部分由头部,体部,尾部三大部分。头部展示title, 体部承载提示信息,尾部定义按钮。其中头部与尾部为可选部分

3. 不论用户单击确定还是取消按钮,弹框都要消失。(当用户注册的“确定”按钮回调函数如果返回false,则不关闭弹框)

4. 用户可设置title,body,以及确定按钮的文字,取消按钮的文字。当title为空时,无header部分,确定与取消按钮哪一个定义了文字就显示哪一个按钮。


下面是参考实现代码:

/**
 * window alert, prompt, and so on
 * @author DavidWang
 * @date 2015-11-13 11:14:30
 * */
;(function($){
	'use strict';
	
	/**
	 * 对话框
	 */
	function Dialog(title){
		if(!(this instanceof Dialog)) return new Dialog(title);
		this.title = title;
		this.dones = [];
		this.fails = [];
		this.alwayses = [];
		
		return this;
	}
	
	Dialog.prototype.title = function(title){
		this.title = title;
		return this;
	};
	
	Dialog.prototype.sureBtn = function(txt1){
		this.btn1 = txt1;
		return this;
	};
	Dialog.prototype.cancelBtn = function(txt2){
		this.btn2 = txt2;
		return this;
	};
	
	/**
	 * body有可能是字符串,也有可能是doc element,或者是jQuery包装过的元素
	 * @param body
	 * @returns {Dialog}
	 */
	Dialog.prototype.body = function(body){
		this.body = body;
		return this;
	};
	/**positive button*/
	Dialog.prototype.done = function(func){
		this.dones.push(func);
		return this;
	};
	/**negative button*/
	Dialog.prototype.fail = function(func){
		this.fails.push(func);
		return this;
	};
	/**always*/
	Dialog.prototype.always = function(func){
		this.alwayses.push(func);
		return this;
	};
	
	/**build the dialog*/
	Dialog.prototype.build = function(){
		var overlay = $('<div>').addClass('dialog-overlay');
		var win = $('<div>').addClass('dialog-window');
		overlay.append(win);
		var me = this;
		//title
		this.title && ((function(){
			var header = $('<div>').addClass('dialog-header');
			if(me.title.jquery){
				header.append(me.title);
			}else{
				header.append($('<h3>',{text: me.title}));
			}
			win.append(header);
		})());
		//body
		var body = $('<div>').addClass('dialog-body');
		body.append(this.body.jquery ? this.body : $('<p>',{text: this.body}));
		win.append(body);
		//footer
		(this.btn1 || this.btn2) && (function(){
			var footer = $('<div>').addClass('dialog-footer');
			me.btn1 && footer.append($('<a>',{text: me.btn1,href:'javascript:void(0)'}).addClass('dialog-btn').click(function(evt){
				me.dones.some(function(fn){
					return fn.call(me) === false;
				}) || me._always();
				
			}))
			me.btn2 && footer.append($('<a>',{text: me.btn2,href:'javascript:void(0)'}).addClass('dialog-btn').click(function(evt){
				me.fails.some(function(fn){
					return fn.call(me) === false;
				}) || me._always();
				
			}))
			win.append(footer);
		}());
		
		overlay.appendTo(document.body);
		this.overlay = overlay;
		
		this.alwayses.push(function(){
			overlay.remove();
		});
		return this;
	};
	Dialog.prototype._always = function(){
		var me = this;
		this.alwayses.forEach(function(fn){
			fn.call(me);
		});
		return this;
	};
	
	Dialog.prototype.go = function(){
		this.overlay.remove();
		return this;
	};
	
	Dialog.alert = function(msg,cb){
		return Dialog().body(msg).sureBtn('确定').done(cb || $.noop).build();
	}
	
	window.Dialog = Dialog;
	
})(window.jQuery);

可以看到上面代码中也定义了一个alert方法,是为了单纯弹一个没有header和footer的框,可通过调用go方法移除弹框。

使用方法可参考下述代码 :

Dialog().title('My Title').body('Really?')
	.sureBtn('Yes').cancelBtn('No')
	.done(function(){
		//单击了Yes
	})
	.fail(function(){
		//单击了No
	})
	.always(function(){
		//弹框关闭,即总会回调的方法
	});


其中的body除了像上面直接写字符串,也可以传入jQuery生成的元素对象,如$('<div>',{text: 'Body'})


此弹框的样式可参考以下代码


@CHARSET "UTF-8";
/**edit by davidwang 2015-11-13 11:37:30 自定义弹框 使用方法参见dialog.js**/

.dialog-overlay{
	position:fixed;
	top:0;
	left:0;
	right:0;
	bottom:0;
}

.dialog-window{
	position:absolute;
	font-family: "Microsoft Yahei",sans-serif;
	top:100px;
	left:50%;
	width:300px;
	margin-left: -150px;
	color:#333;
	border: 1px solid #768995;
	border-radius: 3px 3px 0 0;
}

.dialog-header{
	background-color:#829aa8;
	color:#fff;
	padding:10px;
}
.dialog-header h3{
	font: 14px bold "Microsoft Yahei",sans-serif;
}

.dialog-body{
	background-color:#fff;
	padding:15px;
	font-size:12px;
	border-bottom: 1px solid #d8dee2;
	text-align:center;
}

.dialog-footer{
	background-color:#fff;
	padding:5px;
	text-align:center;
}

.dialog-footer a.dialog-btn{
	margin: 0 10px 0 10px;
	cursor:pointer;
	text-decoration: none;
	font-weight: bold;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章