Bootstrap Modal遮罩弹出层

之前发表过一篇文章叫Bootstrap Modal弹窗代码,其实那个只是一个弹出层代码而已,并不是仿造Bootstrap的,Bootstrap Modal是给外层添加固定fixed,然后内容使用自适应靠上居中方式。今天分享的这篇文章正是这种方式。

HTML结构

考虑到内容区域需要居中对齐,所以至少要有一个div来定位和显示背景,再用一个div居中内容,内容区域想分成header、body和footer。

<div class="rs-dialog" id="myModal1">
	<div class="rs-dialog-box">
		<a class="close" href="#">&times;</a>
		<div class="rs-dialog-header">
			<h3>标题</h3>
		</div>
		<div class="rs-dialog-body">
			<p>内容</p>
		</div>
		<div class="rs-dialog-footer">
			<input type="button" class="close" value="Close" style="float:right">
		</div>
	</div>
</div>

添加样式

透明背景用background和opacity来实现,也可以选择rgba,只是IE8及以下浏览器不支持。为了让一个position为fixed的div铺满整个窗口,可以将其top、right、left、bottom属性全部设为0。

当内容区域过长时,模拟浏览器纵向滚动条,方法是将body(或HTML)的overflow属性设为hidden,禁止浏览器真正的滚动条出现,然后给弹窗最外层的div设置overflow-y:auto,用这个div的滚动条模拟浏览器滚动条。

弹窗打开关闭时滚动效果用css3 transition来实现。

.dialog-open{
	overflow-y:hidden !important;
}
.rs-overlay{
	background:#000;
	opacity:.5;
	filter: alpha(opacity=50);
	position: fixed;
	z-index: 1000;
	top:0;
	bottom:0;
	left:0;
	right:0;
	display: none;
}
.rs-dialog{
	display: none;
	opacity: 0;
	overflow: hidden;
	position: fixed;
	top:0;
	bottom:0;
	left:0;
	right:0;
	z-index: 1040;
	-webkit-overflow-scrolling: touch;
	outline: 0;
	/*background: rgba(0,0,0,.5);*/
	-webkit-transition: opacity .15s linear;
	-o-transition: opacity .15s linear;
	transition: opacity .15s linear;
}
.dialog-open .rs-dialog{
	overflow-x:hidden;
	overflow-y:auto;
}
.rs-dialog.in{
	opacity: 1;
}
.rs-dialog .rs-dialog-box {
  -webkit-transform: translate(0, -25%);
  -ms-transform: translate(0, -25%);
  -o-transform: translate(0, -25%);
  transform: translate(0, -25%);
  -webkit-transition: -webkit-transform 0.3s ease-out;
  -o-transition: -o-transform 0.3s ease-out;
  transition: transform 0.3s ease-out;
}
.rs-dialog.in .rs-dialog-box {
  -webkit-transform: translate(0, 0);
  -ms-transform: translate(0, 0);
  -o-transform: translate(0, 0);
  transform: translate(0, 0);
}
.rs-dialog .rs-dialog-box{
	position: relative;
	margin:30px auto;
	width: 600px;
	background-color: #ffffff;
	border-radius:10px;
	border: 1px solid #999999;
	border: 1px solid rgba(0, 0, 0, 0.2);
	-webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
	box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
}
.logged-in .rs-dialog .rs-dialog-box{
	margin-top:60px;
}
.rs-dialog-box a.close{
	position: absolute;
	top: -12px;
	right: -12px;
	width: 25px;
	height: 25px;
	padding: 0;
	line-height: 25px;
	font-size:20px;
	font-family:Arial,sans-serif;
	font-weight:bold;
	text-decoration:none;
	text-align:center;
	text-shadow: 0 1px 0 #ffffff;
	color: #fff;
	background-color:#8b8b8b;
	border:2px solid #fff;
	border-radius: 25px;
	box-shadow:0 0 3px 1px #999;
	outline: none;
}
.rs-dialog-box a.close:hover{
	background-color:#444;
}
.rs-dialog-header{
	padding: 20px;
	border-bottom: 1px solid #e5e5e5;
}
.rs-dialog-header h3{
	font-size: 18px;
}
.rs-dialog-body{
	padding: 20px;
	line-height: 1.4
}
.rs-dialog-body p{
	margin-bottom:10px;
}
.rs-dialog-footer{
	padding: 20px;
	border-top:1px solid #e5e5e5;
	overflow: hidden;
}
@media (max-width: 767px) {
  .rs-dialog .rs-dialog-box {
    width: auto;
    margin: 30px 20px;
  }
}

添加控制脚本

大部分用css实现,所以脚本通过简单的addClass和removeClass就可以控制开关。

还可以增加点击弹窗外部关闭窗口的功能。

jQuery(document).ready(function($){
	$('body').append('<div class="rs-overlay" />');
	$("a[rel='rs-dialog']").each(function(){
		var trigger 	= $(this);
		var rs_dialog 	= $('#' + trigger.data('target'));
		var rs_box 		= rs_dialog.find('.rs-dialog-box');
		var rs_close 	= rs_dialog.find('.close');
		var rs_overlay 	= $('.rs-overlay');
		if( !rs_dialog.length ) return true;
		// Open dialog
		trigger.click(function(){
			//Get the scrollbar width and avoid content being pushed
			var w1 = $(window).width();
			$('html').addClass('dialog-open');
			var w2 = $(window).width();
			c = w2-w1 + parseFloat($('body').css('padding-right'));
			if( c > 0 ) $('body').css('padding-right', c + 'px' );
			rs_overlay.fadeIn('fast');
			rs_dialog.show( 'fast', function(){
				rs_dialog.addClass('in');
			});
			return false;
		});
		// Close dialog when clicking on the close button
		rs_close.click(function(e){
			rs_dialog.removeClass('in').delay(150).queue(function(){
				rs_dialog.hide().dequeue();
				rs_overlay.fadeOut('slow');
				$('html').removeClass('dialog-open');
				$('body').css('padding-right', '');
			});
			return false;
		});
		// Close dialog when clicking outside the dialog
		rs_dialog.click(function(e){
			rs_close.trigger('click');
		});
		rs_box.click(function(e){
			e.stopPropagation();
		});
	});
});

防止网页内容偏移

打开弹窗时给body增加overflow:hidden属性,导致滚动条消失,这时会使网页的内容往右移动一下,待弹窗打开滚动条再出现时,又会复原,视觉效果不友好。如果在有滚动条的情况下知道其宽度,给body增加padding-right属性就可以抵消这个便宜效果。

这个方法在于江水博客关于弹窗的文章里找到了,在open dialog的click时间中引用了文章提到的最后一种方法。

触发弹窗

最后,根据上面的脚本,触发弹窗的链接如下

<a href="#" rel="rs-dialog" data-target="myModal">Launch Demo Modal</a>

rel=”rs-dialog”表示这是弹窗触发链接

data-target=”myModal”表示要打开HTML ID为myModal的弹窗。

演示和下载

[dmengl2v]演示地址 下载来源[/dmengl2v]


关注我

我的微信公众号:前端开发博客,在后台回复以下关键字可以获取资源。

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
  • 回复「Vue脑图」获取 Vue 相关脑图
  • 回复「思维图」获取 JavaScript 相关思维图
  • 回复「简历」获取简历制作建议
  • 回复「简历模板」获取精选的简历模板
  • 回复「加群」进入500人前端精英群
  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
  • 回复「知识点」下载高清JavaScript知识点图谱

每日分享有用的前端开发知识,加我微信:caibaojian89 交流