进一步封装bootstrap的模态框

前提的话,这里想不到能说些什么,alertconfirmprompt应该是大家都比较熟悉的方法了吧,只是这些个浏览器自带的方法,所展示的样子的,都是那种看起来很丑很丑的样子,所以有些人开始为了能有更好的体验,开始使用自定义的一些信息展示方法,也就是模态框。

概述

到底有多少人在使用模态框,这个暂且不谈,但是有一点就是,你可以以你自己喜欢的样式方法,来展示这些信息,我想让它展示什么样的风格,它就得展示怎么样的风格,听起来很霸气有么有。

我不知道其他人对于代码的掌控,是个什么样的想法,对于我来说,我总是希望我能更好的掌控我的代码,不过,话说,掌控欲太强的人,会让人很难以忍受,想想,难道这就是到现在都还孤身一人的原因么~~~(:

本文想要写的模态框,是基于bootstrap中提供的模态框的基础上,进行了封装,说是封装,在我看来,也就是把一些原本存在的功能,更具体的模块化吧,这样会让我觉得,在使用时,可以更具有逻辑性,可以让我在书写逻辑层代码时,把更多的心思花费在逻辑处理上,而对于模态框的显示部分,交给一些定义好的属性去处理。

如果您对bootstrap的模态框不了解,或者知道的很少的话,可以前往:bootstrap modals查看,而关于模态框的使用方法,这里也不多说。

顺便看下模态框的显示样式吧,插入图片:

不再多说,下面继续看一下,封装之后的模态框所支持的参数,以及使用方法吧。

Mesbox支持的属性

这里,我把封装之后的一个构造函数命名为Mesbox,当使用该模态时,只要new Mesbox(options),即可,其中options是一个对象,该对象中包含着一些初始化该模态框的信息。

options的信息是很重要的,因为除了这个使用的时候,会有这个options的输入,在更改模态框的显示模式时,也是使用的相同格式的对象进行更改模态框模式。

描述 实例
title 模态框的头部显示内容,这个很我觉得应该不需要解释了
id 生成的模态框的div的id,可要可不要,无关整个大局,如果想要在以后找到该模态框,可要通过实例化之后的一个属性进行处理,后面会在一些例子中做介绍
type 这个是很重要的,这个是用来确定模态框的显示格式的,显示alert的样式,那么type需要设置为”alert”,需要显示confirm和prompt的话,type=”confirm”,如果该模态框是为了在ajax请求时,显示正在请求的过程,则type = “ajax”,暂时只支持这三种属性 alert
confirm
ajax
getContent 模态框的内容部分显示,如果是一个函数,那么内容不符,显示该函数的返回值,或者可以使一个字符串,字符串可以是html的代码,甚至是带有可变参数的html代码,按自己喜好来书写。示例可以查看ajax部分的示例,类似。 ajax
applyName 确认按钮显示的名称,比如上图中Save按钮的名称
applyFn 确认按钮,点击之后的回调,需要是函数。该函数内部的this指向这整个模态框。
cancelName 取消按钮的名称,如上图中Close按钮的名称 详情
confirmType 该属性,只有在type=”confirm”时,才起作用,表示,当在confirm对话框中,点击了确认按钮时,接下来的动作时什么,该值默认为空,如果在confirm点击之后,是要执行ajax操作,那么该值需要设置为”ajax”,而需要执行的ajax的操作需要在applyFn内部,重新发起。 详情
ajaxOptions 该值也只有在type=”ajax”时,才属于有效值,设置ajax传输的一些参数,具体包含的参数,请查看下面关于ajaxOptions支持的属性列表 详情

上面的列表是在new Mesbox或者给Mesbox重定义时需要的一些参数设置。下面继续看下,模态框是用于ajax提交的话,ajaxOptions属性中,可以设置的参数类型。

描述
url ajax请求的地址,必须有,没有会报错的
type ajax请求时的请求类型,默认为post类型
data ajax请求时,需要携带的额外参数,格式为”name=value&name1=value1″
dataType ajax返回值的类型,默认为json类型。
success 成功之后的回调函数
showResultType 只有一个属性值,取值为“alert”,该方法,只对返回json格式或者对象格式中,对象中有msg属性值的返回值有效。如果msg的值为空,则该属性是否设置,无关紧要。如果该属性设置为“alert”,并且返回值中有msg的属性值,则会以模态框type=”alert”的形式展示该msg的值,并且在点击确认之后,才会执行ajaxOptions中success回调函数。为了模拟alert阻塞js运行的特性。

OK,上述就是在new Mesbox时,涉及到的一些属性以及其代表的含义,直接看的话,是比较乏味并且看不出什么的,所以接下来会有一些实例,可以更好的了解这些属性,在模态框中起到的作用。

Mesbox实例中的API

因为Mesbox这个功能模块是使用的构造函数的模式实现的,所以有很多可以从实例中访问到的属性,比如传入参数的options对象,比如创建模态框的createBox方法等,但是这些其实都是没有什么用的。

所以,这里对于这些基本不会被使用到的方法,不做说明,下面只对经常使用的几个方法,进行一下说明:

描述
showMbox 显示模态框,模态框的值,是之前实例化或者模式更改时,生成的值
hideMbox 隐藏模态框
reDefineMbox 该方法,是最重要的方法,重新更改模态框的模式,需要传入一个对象作为参数,对象需要的属性和实例化Mesbox时,所需要的属性完全相同,同时,如果在使用该方法时,有些参数未赋值,则会去实例化时传入对象中查找对应的值,如果依然没有,则显示为默认值。

OK了,这个方法中,基本使用者三种API就可以结束了,所以其他的,就不做说明了,因为,也没有用~~~

注:不太常写插件,所以可能有很多地方没有注意到,也没有做一些安全措施的检查等,也许会有很多问题,如果您有什么建议,请指教。

理论部分,就是这些了,下面就看看一些实例的测试吧

模态框的实例化-非阻塞型alert

首先,我们就从最简单的alert模式开始吧,实例化一个alert类型的模态框

那么就可以直接使用以下代码:

	
var mbox = new extendBoot.Mesbox({
	title:"模拟alert",
	type:"alert",
	getContent:"模拟alert-单纯信息展示,点击确认,则关闭该alert",
	applyName:"确定"
});

$("#showAlert").on("click",function(){
	mbox.showMbox();
});
	

您也可以点击,模拟非阻塞alert demo

模拟阻塞alert

只是这个时候,如果alert还有其他的逻辑,那么会直接在显示出该内容的之后,继续执行后面的代码,也就是说,这个时候的alert模态框,是非阻塞的alert模态框,这个和我们平时所见到的就有些不相同了,所以,如果你想要一个阻塞的alert模态框,那么你可以使用下面的方法:

	
var mbox = new extendBoot.Mesbox({
	title:"模拟阻塞alert",
	type:"alert",
	getContent:"模拟alert-单纯信息展示,点击确认,则执行回调",
	applyName:"确定",
	applyFn:function(){
		alert("clicked!");
	}
});

$("#showAlert").on("click",function(){
	mbox.showMbox();
});
	

毕竟JS就是非阻塞的语言,所以如果想要模拟阻塞的行为,那么就只能使用回调函数做这个处理了,所以,看上面代码中,进行实例化时,只要给确定按钮上,添加一个回调函数,把需要在点击“确认”之后,再执行的代码,放入这个回调,即可模拟alert的阻塞行为。

查看demo地址:Mbox-alert-fn

alert的模态框是这个模态框的基础,它会在confirmajax模式中,被使用来显示一些提示性信息,这个我们下面慢慢看。

confirm的模态框

看到了上面的阻塞型alert模态框,再想想confirm模态框,就显得很简单了,其实也就是多出一个取消按钮而已,所以这个confirm的实现,说起来就更简单,代码可以如下:

	
var mbox = new extendBoot.Mesbox({
	title:"模拟confirm",
	type:"confirm",
	getContent:function(){
		var html = "";
		html += "模拟confirm,单纯信息展示<br />";
		html += "点击确认,则执行其他代码<br />";
		html += "点击取消,不执行";
		return html;
	},
	applyName:"确定",
	applyFn:function(){
		alert("clicked!");
	},
	cancelName:"取消"
});

$("#showAlert").on("click",function(){
	mbox.showMbox();
});
	

本示例的demo请查看:Mbox-confirm-baisc.html

在代码从上面可以看到,在模态框的内容显示部分,getContent既可以是直接以字符串的形式表示,也可以使用函数表示,显示的内容为getContent函数返回的字符串或者html代码。

可操作型confirm模态框

这里之所以把这个标题定义成可操作性confirm模态框,也可以说,这其实就是模拟prompt功能的而已,但是在我这个方法中,却是以confirm的形式去实现的这个方法。那么实现方法如下:

	
var mbox = new extendBoot.Mesbox({
title:"模拟confirm",
  type:"confirm",
  getContent:function(){
	var html = "";
	html = '<form class="form-horizontal" role="form">'+
	  '<div class="form-group">'+
	  '<label for="name" class="col-sm-2 control-label">'+
	  '姓名:</label>'+
	  '<div class="col-sm-10">'+
	  '<input type="email" class="form-control" id="name" placeholder="name">'+
	  '</div></div>'+
	  '</form>';
	return html;
},
  applyName:"确定",
  applyFn:function(){
    //var obj = this;
    //这里,obj == mboxDiv,他们表示的是同一个对象
    //您可以使用下面的方法,来确认这个问题
    console.log(this == mboxDiv);
    var name = $.trim(mboxDiv.find("#name").val()),
      str = "您没有输入名字!";
    if(name){
      str = "您输入的名字是:"+name;
    }
    alert(str);
  },
  cancelName:"取消"
}),
mboxDiv = mbox.Mbox;
//mbox.Mbox中保存的对象,就是该模态框最顶层的jQuery对象。
//可以通过该对象对内容区域添加事件绑定
//获取内容区域的一些元素的值等操作。

$("#showAlert").on("click",function(){
	mbox.showMbox();
});
	

该方法的demo示例页面:Mbox-confirm-prompt

记得在上面介绍时,有说过,为什么可以不给该方法添加id么,因为在实例化时,会有一个属性用来保存该对象,就是上述代码中的Mbox属性,所以,就可以通过mbox.Mbox的方法,访问到这个新生成的DIV,而不需要再获取到id,然后使用id去查找该html的对象。

并且,在回调函数applyFn的内部,this的指向也是指向mbox.Mbox的,所以如果是在applyFn内部使用,也可以直接使用this对象,访问到生成的该DIV,所以说,这里的id其实是可有可无的。

当然,有一点就是我们习惯在使用jQuery时,给this对象在jQuery实例化一次,这里也是可以再使用一次的,没有什么问题,只是有下面的差别而已:

	
this == mbox.Mbox; //true
$(this) == mbox.Mbox; // false
//因为$进行实例化的,就会生成同一个对象,所以不等。
//其实就和你定义两个空对象,它们也不相等,是一个原因
{} == {} // true
	

模拟ajax请求

ajax区别于之前alertconfirm方法的地方在于,ajax的输入框在被触发时,首先是一个loadding的界面,这个在使用new进行实例化的同时就会被触发,所以在使用时,并不能像前面的代码一样的,单纯实例化后,使用showBox即可。

那么这里,具体怎么使用是最好的,就先看下最基本的使用方法,也就是,在实例化时,就进行了ajax的请求,并且,ajax的请求的模态框中,是没有footer部分的,所以最简单的ajax请求的实例化结构,就如下代码所示:

插入代码:

				
var mbox = new extendBoot.Mesbox({
	title:"模拟ajax",
	type:"ajax",
	ajaxOptions:{
		url:"/ajax/succ.php",
		type:"get",
		success:function(){
			alert("123");
		}
	}
});

$("#showAlert").on("click",function(){
	mbox.showMbox();
});
				
			

您可以点击链接,查看demo

因为在提交的过程中,可能会因为返回信息过快,而导致看不到loadding的界面,就到了ajax结果的处理模块了,但是因为在ajax成功之后,没有信心的展示,所以这里当你再点击右侧的按钮时,弹出的模态框的内容,就是loadding的样式。

结合阻塞alert模式的ajax模态框

因为我们也都知道,在ajax提交之后,有可能会是成功之后进行页面跳转,那么就会出现一个问题了,就是在成功之后,就会立马跳转,但是呢,我又想要在ajax提交之后,首先显示一下提交成功或者失败的原因,当点击确认之后,再做跳转或者其他的一些动作处理。

如果您有认真查看之前的示例的话,那么其实是可以看到如何处理的,就是在ajax的模态框的的ajaxOptionssuccess内部,继续调用alert的模态框,并结合alert阻塞模式的applyFn回调,实现这个功能,当然了,这个也是我下面要说的方法的实现原理。

因为会经常碰到这样的问题,所以,这里我给ajax的方法,提供了一个更简单的属性值,可以修改,以实现刚刚提到的这个问题。

那就是在ajaxOptions的属性中,添加一个额外的属性showResultType,取值暂时只有一个showResultType:"alert",如果设置了该值,会首先弹出一个alert的模态框,并显示ajax返回的msg属性值,当点击确认之后,才会继续执行ajaxsuccess的回调方法。

看下面的示例:

	
$("#showAlert").one("click",function(){
	var mbox = new extendBoot.Mesbox({
		title:"模拟ajax",
		type:"ajax",
		ajaxOptions:{
			url:"/ajax/succ.php",
			type:"get",
			success:function(data){
				alert(data.msg);
			},
			showResultType:"alert"
		}
	});
	mbox.showMbox();
});
	

点击可以查看:demo地址:

但是,有个问题很快就出现了,这样的写法,每次只能绑定一次啊,这不可行的,总不能我每实现一个ajax提交信息,就new一个新的Mbox对象吧?

当然不行,这效果也太差了,所以,就有了另外一个方法,就是重写整个Mbox的方法reDefineMbox,前面说过,这个方法传入的参数和实例化Mbox时,是完全相同的,所以继续看下面关于reDefineMbox的使用。

reDefineMbox方法使用

前面说过,reDefineMbox方法的使用和实例化时,各参数的含义是完全相同的,所以,首先来看前面这个本小节前面一小节ajaxalert结合的方法,使用reDefineMbox方法实现,是怎么样的情况:

代码:

	
var mbox = new extendBoot.Mesbox({
	title:"模拟ajax",
});
$("#showAlert").on("click",function(){
	mbox.reDefineMbox({
		type:"ajax",
		ajaxOptions:{
			url:"/ajax/succ.php",
			type:"get",
			success:function(data){
				alert(data.msg);
			},
			showResultType:"alert"
		}
	});
});
	

可以查看:demo地址

在demo页面中,你可以看到一中情况就是,你每次点击按钮时,都会提出一次ajax请求,并且使用同一个Mbox对象,这样的好处就是,可以不要创建多于的对象。

举个简单的例子,当你在页面中,需要使用很多alert对象方法时,如果使用该模态框的alert方法,那么就可以只实例化一个Mbox方法,就可以使用reDefineMbox方法,进行N多种样式的alert信息展示

下面我们进行一个简单的测试:

	
var msgList = [{
	title:"alert1",
	content:"alert1 content"
  },{
	title:"alert2",
	content:"alert2 content",
	applyFn:function(){
		alert("alert2");
	}
  }],
  i=0,
  len = msgList.length;
var mbox = new extendBoot.Mesbox({
	title:"reDefineMbox 多次使用alert",
});
$("#showAlert").on("click",function(){
  if(i >= len){
	i=0;
  }
  var msg = msgList[i];
  mbox.reDefineMbox({
	type:"alert",
	title:msg.title,
	getContent:msg.content,
	applyFn:msg.applyFn
  });
  i++;
});	
	

可以查看:demo地址

而对于confirmajax等,都是可以如此实现的,只要能熟悉的使用,那么就可以配合达到你想要的很多种效果。

比如,弹出框中显示的是一些html代码,而这些代码还有一些简单的交互,只有点击确认之后,才会执行后面的一些动作,就可以结合confirmajax,实现该功能,结构如下:

	
$("#showAlert").on("click",function(){
  mbox.reDefineMbox({
	title:"reDefineMbox ajax confirm",
	type:"confirm",
	getContent:function(){
	  return '<div class="form-group">'+
		'<label for="name">Name</label>'+
		'<input type="text" class="form-control"'+
		'id="name" placeholder="Enter name" name = "name">'+
	    '</div>'+
	    '<div class="form-group">'+
		'<label for="phone">Phone</label>'+
		'<input type="number" class="form-control"'+
		'id="phone" placeholder="phone" name = "phone">'+
	    '</div>';
	  },
	  applyFn:function(){
		var obj = $(this),
		  //applyFn内部的this,是指向mbox的,
		  //所以,可以使用this找到该mbox,也可以使用this
		  name = obj.find("#name"),
		  phone = obj.find("#phone");
		var data = name.attr("name")+"="+name.val()+"&"+phone.attr("name")+"="+phone.val();
		
		mbox.reDefineMbox({
		  type:"ajax",
		  ajaxOptions:{
			url:"/ajax/succ.php",
			type:"get",
			data:data,
			dataType:"json",
			success:function(data){
			  alert(data.msg);
			},
			showResultType:"alert"
		  }
		});
      },
	confirmType:"ajax"
  });
});
	

查看:demo地址

说到这里,其实也就差不多说完了,也许有些功能并没有完善,我只是把我想到的功能给添加上了,并且这样可能代码需要很多,但是我觉得更有逻辑性,并且,当我需求更改时,我能更好更快的找到我可以更改的代码,感觉可控性更强,所以就实现了一个这样的封装。

当然啦,因为本身就是基于bootstrap的已有功能封装的,所以浏览器的支持,是有限制的~~~

如果有兴趣,可以直接在在demo页面,查看源码,该部分的JS代码,是没有压缩的。

本文地址:http://www.zhangyunling.com/?p=273

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>