自定義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;
}


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