Confirm({ msg: '您选择的订单状态不符合当前操作的条件,请确认是否要继续操作!', onOk: function(){ }, onCancel: function(){ } });
onCancel是在点击取消按钮时候的回调。不管onOk和onCancel回调有没有,点击按钮的时候都要关闭弹框。onCancel回调可以没有。
3)自定义modal框
原型:
调用形式:
var modal = new Modal({ title: '', content: '', width: 600, buttons: [ { html: '<button type="button">确定</button>', selector: '.btn-ok', callback: function(){ //点击确定按钮的回调 } }, { html: '<button type="button">取消</button>', selector: '.btn-cancel', callback: function(){ //点击取消按钮的回调 } } ], onContentReady: function(){ //当modal添加到DOM并且初始化完毕时的事件回调,每个modal实例这个回调只会被触发一次 }, onContentChange: function(){ //当调用modal.setContent类似的方法改变了modal内容时的事件回调 }, onModalShow: function(){ //当调用modal.open类似方法显示modal时都会触发的事件回调 }, onModalHide: function(){ //当调用modal.hide类似方法隐藏modal时都会触发的事件回调 } }); $('#btn-audit').click(function(){ modal.open(); });
跟Alert和Confirm不同的是,一个页面里面只需要一个Alert和Confirm的实例,但是可能需要多个Modal的实例,所以每个Modal对象都需要单独new一下。由于每个Modal要完成的事情都不相同,所以:
需要一个title参数来设置名称,表达这个Modal正在处理的事情;
content参数表示Modal的html内容;
width参数设置Modal的宽度,Modal的高度保持auto;
buttons参数用来配置这个Modal上面的按钮,一般情况下Modal组件只需要两个按钮(确定和取消)就够了,但也有少数情况需要多个按钮,所以把按钮做成配置的方式相对灵活一点,每个按钮用三个参数来配置,html表示按钮的html结构,selector方便注册回调的时候通过事件委托的方式来处理,callback配置按钮点击时的回调;
onContentReady这个事件回调,可以在Modal初始化完毕的时候,主动去初始化Modal内部html的一些组件;由于组件初始化一般只进行一次,所以放在这个回调里面最合适;
onContentChange回调,在一个Modal需要被用作不同的场景,显示不同的HTML的内容时会派上用场,但是不是非常的好用,处理起来逻辑会稍微偏复杂,如果一个Modal实例只做一件事情的时候,onContentChange这个回调就用不到了;
onModalShow这个回调在每次显示Modal的时候都会显示,使用的场景有很多,比如某个Modal用来填写一些表单内容,下次填写的时候需要reset一下表单才能给用户使用,这种处理在这个回调里面处理就比较合适;
onModalHide这个回调有用,不过能够用到的场景不多,算是预留的一个接口。
4)其它需求
所有类型的弹框都做成虚拟模态的形式,显示框的同时加一个遮罩;
所有框都不需要支持拖动和大小调整;
alert和dialog框的标题,按钮数量、按钮位置、按钮文字都固定。
实际上:
遮罩这个效果,bootstrap的modal组件本身就已经支持了;
拖动和大小调整,这个功能属于锦上添花,但是对软件本身来说,并一定有多少额外的好处,所以我选择不做这种多余的处理;
alert和dialog不需要做太过个性化,能够统一风格,改变浏览器原生的弹框体验即可。
5)DEMO中调用实例
接下来演示下我在完成这三个组件开发之后,实际使用过程中调用这些组件的方式:
var modal = new Modal({ title: '测试modal', content: $('#modal-tpl').html(), width: 500, onOk: function(){ var $form = this.$modal.find('form'); var data = $form.serializeArray(); var postData = {}; data.forEach(function(obj){ postData[obj.name] = obj.value; }); if(!postData.email) { Alert('请输入EMAIL!'); return false; } var deferred = $.Deferred(); if(!postData.password) { Confirm({ msg: 'Password为空,是否要继续?', onOk: function(){ _post(); }, onCancel: function(){ deferred.reject(); } }) } else { _post(); } return $.when(deferred); function _post(){ //模拟异步任务 setTimeout(function(){ if(postData.email === 'admin@admin') { Alert({ msg: '提交成功!', onOk: function(){ deferred.resolve(); } }); } else { Alert({ msg: '提交失败!', onOk: function(){ deferred.reject(); } }); } },3000); } }, onModalShow: function () { var $form = this.$modal.find('form'); $form[0].reset(); } }); $('#btn-modal').click(function () { modal.open(); });
3. 实现要点
1)最基础的一点,要对bootstrap的modal组件源码有所了解:
初始化方式:$modal.modal()
打开:$modal.modal('show')
关闭:$modal.modal(hide)
事件:bootstrap大部分带过渡效果的组件的事件都是成对的,并且一个是现在时,一个是完成时,modal组件定义了2对:
show.bs.modal和shown.bs.modal,hide.bs.modal和hidden.bs.modal。