这个是原文链接http://www.w3cfuns.com/notes/16843/3cb0d0be195ec2ea4b50f0c51cc81224

这个是他的js代码

/**工厂构造函数*/
	Factory = function(configs){
		var _i = this, c = _i.options;
		_i.config = $.extend({}, c, configs);
		
		//实例化弹窗
		if(!(_i instanceof Factory)){
			return new Factory(configs);
		}
		_i.init();
	};
	Factory.prototype = {
		options: {
			dom: "xy-ui-pop",			//标识弹窗,用于关闭所有
			id: "uiPop",					//弹窗ID (不同ID对应不同弹窗)
			title: "提示",				//标题(为false时隐藏标题)
			content: "",					//消息内容
			type: "warning",			//图标类型 warning|error|success|confirm
			padding: "20px",			//内容填充区域
			lock: 1,						//锁定屏幕(遮罩)
			fixed: false,					//是否固定定位
			zIndex: 9999,				//设置元素层叠
			time: 0,						//定时关闭
			
			btn: "确定",					//按钮(String/Array) 	btn:"确定" | btn:["确定", "取消"] | btn: ['按钮1', '按钮2', '按钮3', …]
			onShow: null,				//打开弹窗成功回调方法
			onOk: null,					//确定按钮回调方法
			onClose: null,				//关闭按钮回调方法
			bottom: true,				//底部(为false时隐藏底部)
			
			alpha: [".4", "#000"],	//设置遮罩层背景及透明度
			skinPath: "skin/"			//css或image路径
		},
		init: function(){
			var _i = this, opt = _i.config, c = null, popWin = null, offsetL, offsetT;
			
			_i.isfixed = (opt.fixed || opt.time) ? true : false;
			
			if($("#" + opt.id)[0])
				return;
			
			c = $("<div id='"+opt.id+"' class='"+opt.dom+"'></div>");
			c.html(
				/**遮罩*/
				(opt.lock ? '<div class="xy-ui-overlay"></div>' : '')
				/**窗体*/
				+ '<div class="xy-ui-wrapper anim-ui-wrapper">'
					/*标题区域*/
					+ (opt.title ? '<div class="xy-ui-head"><div class="xy-ui-title">'+opt.title+'</div><a class="xy-ui-close"></a></div>' : '')
					/*内容区域*/
					+ '<div class="xy-ui-body">'
					+	(opt.type ? '<div style="text-align:center;"><span style="background:url('+ opt.skinPath + opt.type +'_icon.gif) no-repeat 0 center;display:inline-block;padding:0.75rem 0 0.75rem 2.625rem;">' + opt.content + '</span></div>' : opt.content)
					+ '</div>'
					/*底部区域*/
					+ (opt.bottom && opt.btn ? function(){
						/*定义多个按钮*/
						var btn = "";
						typeof opt.btn === "string" && (opt.btn = [opt.btn]);
						$.each(opt.btn, function(i, v){
							btn += '<a class="ui-btns xy_ui_btn'+i+'" style="width: '+ (100 / opt.btn.length)+'%">'+v+'</a>';
						});
						return '<div class="xy-ui-foot">'
						+ '<div class="xy-ui-btns">'+ btn +'</div>'
						'</div>'
					}() : '')
				+ '</div>'
			);
			$("body").append(c); //插入到body最后
			
			/**锁屏设置*/
			_i.overlay = c.find(".xy-ui-overlay");
			_i.overlay.css({
				"background-color": opt.alpha[1] || "#000",
				"opacity": 0,
				"z-index": _i.maxIndex() + 1
			}).fadeTo(300, opt.alpha[0]);
			
			_i.popWin = popWin = c.find(".xy-ui-wrapper");
			popWin.css({
				"position": _i.isfixed ? "fixed" : "absolute",
				"z-index": _i.maxIndex() + 1
			});
			
			_i.body = _i.popWin.find(".xy-ui-body");
			_i.body.css({
				"padding": opt.padding
			});
			
			offsetL = ($(window).width() - popWin.outerWidth()) / 2;
			offsetT = ($(window).height() - popWin.outerHeight()) / 2;
			
			/**弹窗定位*/
			popWin.css({
				"left": _i.isfixed ? offsetL : $(document).scrollLeft() + offsetL,
				"top": _i.isfixed ? offsetT : $(document).scrollTop() + offsetT
			});
			
			/**弹窗重置*/
			_i.setPos = function(){
				if(!_i.isfixed){
					popWin.css({
						"left": $(document).scrollLeft() + ($(window).width() - popWin.outerWidth()) / 2,
						"top": $(document).scrollTop() + ($(window).height() - popWin.outerHeight()) / 2
					});
				}else{
					popWin.css({
						"left": ($(window).width() - popWin.outerWidth()) / 2,
						"top": ($(window).height() - popWin.outerHeight()) / 2
					});
				}
			}
			$(window).resize(_i.setPos);
			
			_i.ui_overlay = c.find(".xy-ui-overlay");
			_i.ui_close = c.find(".xy-ui-close");
			
			//弹窗事件
			_i.callback();
		},
		callback: function(){
			var _i = this, opt = _i.config;
			
			opt.onShow && opt.onShow(_i);
			//弹窗自动关闭
			if(opt.time){
				setTimeout(function(){
					_i.close();
				}, opt.time * 1000);
			}
			
			//按钮事件
			_i.popWin.find(".xy-ui-btns a").on("click", function(){
				var index = $(this).index();
				
				if(index === 0){ //默认是确定按钮 [第一个按钮,可以写btn1]
					opt.onOk ? (_i.close(), opt.onOk(_i)) : _i.close();
				}else if(index === 1){ //默认是取消按钮 [第二个按钮,可以写btn2]
					_i.close();
				}else{
					opt["btn" + (index+1)] && _i.close();
				}
				opt["btn" + (index+1)] && opt["btn" + (index+1)](_i);
			});
			//右上角关闭
			if(_i.ui_close[0]){
				_i.ui_close.on("click", function(){
					_i.close();
				});
			}
			
			//点击锁屏重置窗体位置 (双击关闭弹窗)
			_i.ui_overlay.on("click", function(){
				_i.setPos();
			});
		},
		//关闭弹窗
		close: function(){
			var _i = this, opt = _i.config;
			
			if($("#" + opt.id)){
				$("#" + opt.id).remove();
			}
			opt.onClose && opt.onClose(_i); //执行关闭事件
		},
		//关闭页面所有弹窗(根据页面唯一弹窗标识)
		closeAll: function(){
			$("." + this.config.dom).each(function(){
				$(this).remove();
			});
		},
		//获取弹窗最大层级
		maxIndex: function(){
			for(var idx = this.config.zIndex, elem = $("*"), i = 0, len = elem.length; i < len; i++)
				idx = Math.max(idx, elem[i].style.zIndex);
			return idx;
		}
	};

  

他给工厂函数定义了两种 实例化的方式

一种 可new 一种 无需new自new的方式 

说下 无new的方式 Factory

这里 执行的Factory({..})就可以直接调用他的方法  ,此时 函数内部的this指向并不是Facotory而是window,为啥 因为还没有实例化 。

所以 里面的if(!(this instanceof Factory))是成立的 于是在开始执行 实例化 ,但是 他又多走了一步 实例的调用 此时 new Factory({..});里的this指向就是Factory,现在if(!(this instanceof Factory))是不成立的

于是  他开始 执行初始化的操作 this.init();

问? 为啥要复杂化 纯粹是为了兼顾两种调用方式么 

 

posted on 2016-03-08 11:11  Tadini  阅读(306)  评论(0编辑  收藏  举报