最新版本的bootstrap3也是刚发布的,中文文档是5月4日的,相比bootstrap2有很多的改进,新增了也移除了很多class。
1、需求说明:
模态对话框(Modal Dialogue Box,又叫做模式对话框),是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。如单击【确定】或【取消】按钮等将该对话框关闭。
现在我有一个需求:当点击一个按钮时,弹出一个新窗口,窗口中的内容,或用js指定,或通过ajax异步获取服务器端HTTP请求来的数据
实现这样的需求有很多种插件,比如jquery.artDialog.js,但本文主要研究的是基于bootstrap3的模态框而封装的,bootstrap3中的实例内容还是比较粗糙的,在bootstrap3中有2种实现方式,下面我给出详细的案例。
2、模态框在bootstrap3中的实现。
(啰嗦几句)、引入必要的文件
<link href="http://cdn.bootcss.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="http://cdn.bootcss.com/jquery/1.7.2/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
这里使用的是免费的CDN资源公用库。实际生产环境可以增加对 “对象是否加载”的判断,若未加载,那就引入一个本地的js文件。其实官网的说明也是很极致了:
“Bootstrap中文网为Bootstrap构建了自己的CDN加速服务,并且采用国内云厂商的CDN服务,访问速度更快、加速效果更明显、没有速度和带宽限制、永久免费。Bootstrap中文网还对大量的开源工具库提供了CDN服务”
方式1、通过data属性,在页面中无任何JS代码,无需编写JavaScript代码即可生成一个对话框。在一个主控元素,例如按钮,上设置data-toggle="modal"
,然后再设置data-target="#foo"
或href="#foo"
用以指向某个将要被启动的对话框。实例如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="http://cdn.bootcss.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="http://cdn.bootcss.com/jquery/1.7.2/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<title>bootstrap模态框</title>
</head>
<body>
<a href="#myModal" role="button" class="btn" data-toggle="modal">授权</a><br />
或者这样写<br />
<a role="button" class="btn" data-toggle="modal" data-target='#myModal'>授权</a>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">腾讯微博采集</h4>
</div>
<div class="modal-body">
采集中。。。。。。。
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script>
$(function () {
$('.btn').on('click', function() {
$('#myModal').modal();
})
})
</script>
</body>
</html>
方式2、通过js,”仅用一行JavaScript代码即可启动id为
myModal
的对话框“,实现如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="http://cdn.bootcss.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="http://cdn.bootcss.com/jquery/1.7.2/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<title>bootstrap模态框</title>
</head>
<body>
<a role="button" class="btn">授权</a>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">腾讯微博采集</h4>
</div>
<div class="modal-body">
采集中。。。。。。。
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script>
$(function () {
$('.btn').on('click', function() {
$('#myModal').modal();
})
})
</script>
</body>
</html>
通过方法1和方法2对比,我们可以看出,无论是哪种方法,我们都需要在静态页面中构造模态框的HTML代码,即ID为myModal中的代码。这样会使整个页面的代码乱糟糟的,那么ID为myModal中的代码我不希望他在我当前页面显视出现,怎么办呢?答案是把ID为myModal中的代码通过JS封装,使用封装的js能让页面的主要内容干净且对seo友好.
3、基于bootstrap3模态框的插件-czf_modal.js
严格意义上,这个插件是在Dan Caragea先生/女士的基础上做了改进,最主要的sco_modal.js是建立在bootstrap2.3.1的基础上,已经不适用于bootstrap3了。
现在贴上czf_modal.js的代码
;(function($, undefined) {
var pluginName = 'czf_modal';
function Modal(options) {
this.options = $.extend({}, $.fn[pluginName].defaults, options);
this.$modal = $(this.options.target).attr('class', 'modal fade').hide();
var self = this;
function init() {
if (self.options.title === '') {
self.options.title = ' ';
}
};
init();
}
$.extend(Modal.prototype, {
show: function() {
var self = this
,$backdrop;
if (!this.options.nobackdrop) {
$backdrop = $('.modal-backdrop');
}
if (!this.$modal.length) {
var mdstr = '<div class="modal fade" id="' + this.options.target.substr(1) + '" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">';
mdstr += '<div class="modal-dialog">';
mdstr += '<div class="modal-content">';
mdstr += '<div class="modal-header">';
mdstr += '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>';
mdstr += '<h4 class="modal-title" id="myModalLabel"></h4>';
mdstr += '</div>';
mdstr += '<div class="modal-body">';
mdstr += '采集中。。。。';
mdstr += '</div>';
mdstr += '<div class="modal-footer">';
mdstr += '<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>';
mdstr += '</div>';
mdstr += '</div>';
mdstr += '</div>';
mdstr += '</div>';
//mdstr += '<div class="inner"/></div></div></div></div>';
this.$modal = $(mdstr).appendTo(this.options.appendTo).hide();
//this.$modal = $('<div class="modal fade" id="' + this.options.target.substr(1) + '"><div class="modal-header"><a class="close" href="#" data-dismiss="modal">×</a><h3> </h3></div><div class="inner"/></div>').appendTo(this.options.appendTo).hide();
}
this.$modal.find('.modal-header h4').html(this.options.title);
if (this.options.cssclass !== undefined) {
this.$modal.attr('class', 'modal fade ' + this.options.cssclass);
}
if (this.options.width !== undefined) {
this.$modal.width(this.options.width);
}
if (this.options.left !== undefined) {
this.$modal.css({'left': this.options.left});
}
if (this.options.height !== undefined) {
this.$modal.height(this.options.height);
}
if (this.options.top !== undefined) {
this.$modal.css({'top': this.options.top});
}
if (this.options.keyboard) {
this.escape();
}
if (!this.options.nobackdrop) {
if (!$backdrop.length) {
$backdrop = $('<div class="modal-backdrop fade" />').appendTo(this.options.appendTo);
}
$backdrop[0].offsetWidth; // force reflow
$backdrop.addClass('in');
}
this.$modal.off('close.' + pluginName).on('close.' + pluginName, function() {
self.close.call(self);
});
if (this.options.remote !== undefined && this.options.remote != '' && this.options.remote !== '#') {
this.$modal.find('.modal-body').load(this.options.remote);
} else {
this.$modal.find('.modal-body').html(this.options.content);
}
this.$modal.show().addClass('in');
return this;
}
,close: function() {
this.$modal.hide().off('.' + pluginName).find('.inner').html('');
if (this.options.cssclass !== undefined) {
this.$modal.removeClass(this.options.cssclass);
}
$(document).off('keyup.' + pluginName);
$('.modal-backdrop').remove();
if (typeof this.options.onClose === 'function') {
this.options.onClose.call(this, this.options);
}
return this;
}
,destroy: function() {
this.$modal.remove();
$(document).off('keyup.' + pluginName);
$('.modal-backdrop').remove();
this.$modal = null;
return this;
}
,escape: function() {
var self = this;
$(document).on('keyup.' + pluginName, function(e) {
if (e.which == 27) {
self.close();
}
});
}
});
$.fn[pluginName] = function(options) {
return this.each(function() {
var obj;
if (!(obj = $.data(this, pluginName))) {
var $this = $(this)
,data = $this.data()
,opts = $.extend({}, options, data)
;
if ($this.attr('href') !== '' && $this.attr('href') != '#') {
opts.remote = $this.attr('href');
}
obj = new Modal(opts);
$.data(this, pluginName, obj);
}
obj.show();
});
};
$[pluginName] = function(options) {
return new Modal(options);
};
$.fn[pluginName].defaults = {
title: ' ' // modal title
,target: '#modal' // the modal id. MUST be an id for now.
,content: '' // the static modal content (in case it's not loaded via ajax)
,appendTo: 'body' // where should the modal be appended to (default to document.body). Added for unit tests, not really needed in real life.
,cache: false // should we cache the output of the ajax calls so that next time they're shown from cache?
,keyboard: false
,nobackdrop: false
};
$(document).on('click.' + pluginName, '[data-trigger="modal"]', function() {
$(this)[pluginName]();
if ($(this).is('a')) {
return false;
}
}).on('click.' + pluginName, '[data-dismiss="modal"]', function(e) {
e.preventDefault();
$(this).closest('.modal').trigger('close');
});
})(jQuery);
4、如何使用:
下面我们用czf_modal.js对2部分中两种方法的内容进行改造。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="http://cdn.bootcss.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="http://cdn.bootcss.com/jquery/1.7.2/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="/Public/static/bootstrap/js/czf.modal.js"></script>
<title>bootstrap模态框</title>
</head>
<body>
方法1:<a href="/ajax.php" role="button" class="btn" data-trigger="modal" data-title="我是个title">授权</a><br /><br />
方法2:<a href="#" role="button" class="btn" id="btnid">授权</a><!--href必须加#-->
<script>
$(function () {
$('#btnid').on('click', function() {
$(this).czf_modal({
title: '腾讯微博采集',
content: "采集中....",
cache:true,
remote:"ajax.php"
});
//remote();或者在这里加ajax函数,将内容加载到.modal-body中
})
})
</script>
</body>
</html>
ajax.php为同一域下的服务端文件,方法2中如果要加载远程文件 href="#",不能为空。
以下文章帮助理解本文