JavaScript实现居中弹出层与遮罩层的完整教程

作者:页面旅途时间:2026-10-30 03:42:15浏览:287

本文详解如何使用JavaScript动态创建遮罩层与弹出层,实现类似百度登录的弹窗效果。重点解析通过JS计算页面宽高实现弹出层在可视区域绝对居中,利用固定定位与z-index层级控制确保弹窗显示在遮罩之上,并提供兼容多浏览器的EventUtil事件处理对象代码。

弹出层功能概述

弹出层交互功能在实际开发中应用广泛,许多网站利用该机制实现用户登录与注册模块,例如百度首页的登录入口即采用此方式。

弹出层功能概述

此类弹出层的核心特征在于:当用户点击登录或注册按钮时,界面中央会浮现对应的操作区域,同时背景生成半透明遮罩。为确保弹出层内容可见,其z-index层级必须高于遮罩层。此外,点击关闭按钮或遮罩区域应能触发弹窗关闭逻辑(部分网站未实现点击遮罩关闭的功能)。

本文演示一个类似的弹出层实现案例,最终效果如下所示。

弹出层功能概述

接下来简要阐述实现该效果的技术路径。

遮罩层的动态创建

首先处理遮罩层。遮罩层需在页面动态加载过程中通过JavaScript生成,因其需覆盖整个页面视口,故高度需通过JS动态计算获取,宽度则直接设置为页面全宽。同时,需赋予其较大的z-index值以覆盖页面内容,并设置透明度以实现背景模糊效果。


#mask{ 
background: #000;
opacity: .6;
filter:alpha(opacity=60);
position:absolute;
left:0;
top:0;
width:100%;
height:1000px;/*动态获取,这里设置高度是为了测试*/
z-index:1000;
}

具体实现上,通过JavaScript动态创建遮罩层节点并将其插入DOM树:


//创建遮罩层节点
var oMask = document.createElement('div');
oMask.id = 'mask';
oMask.style.width = pageWidth + 'px';
oMask.style.height = pageHeight + 'px';
document.body.appendChild(oMask);

上述代码中的pageWidth和pageHeight变量分别代表页面的宽度与高度值,通过


//获取页面的高度和宽度
var pageHeight = document.documentElement.scrollHeight;
var pageWidth = document.documentElement.scrollWidth;

相关方法获取。至此,遮罩层的构建即告完成。

弹出层的居中定位算法

接下来讨论弹出层的具体表现。

弹出层需显示在页面可视区域的正中央,这是实现的关键步骤。这意味着弹出层距离页面左侧与右侧的间距相等,距离顶部与底部的间距也相等,且所有计算均基于可视区域(viewport)。

弹出层功能概述  

该位置关系可用数学公式表达为:

left = right = (页面可视区域宽度 - 弹出层宽度) / 2;top = bottom = (页面可视区域高度 - 弹出层高度) / 2。

在此案例中,可视区域宽度等同于页面总宽度,因为页面底部未出现滚动条。若页面存在滚动条,计算逻辑需相应调整,但此类情况较为少见。在设置left和top属性前,必须确保弹出层元素已添加到页面DOM中,否则无法正确获取其尺寸进行定位计算。


oLogin.style.left = (pageWidth - loginWidth) / 2 + 'px';
oLogin.style.top = ( clientHeight- loginHeight) / 2 + 'px';

此处需特别提示:弹出层应采用固定定位(position: fixed),且其z-index值必须大于遮罩层的z-index值,以保证弹窗始终显示在遮罩上方。


#login{position:fixed;width:400px;height:400px;background:#fff;z-index: 1001;}

关闭事件与兼容性处理

最后一步是为关闭按钮绑定事件响应函数。


EventUtil.addHandler(oClose, 'click', function(){
document.body.removeChild(oMask);
document.body.removeChild(oLogin);
});

EventUtil是一个用于兼容不同浏览器事件处理机制的工具对象,其具体实现代码如下:


var EventUtil = {
//添加事件处理函数
addHandler: function(element, type, handler){
if(element.addEventListener){
element.addEventListener(type, handler, false);
}else if(element.attachEvent){
element.attachEvent('on' + type, handler);
}else{
element['on' + type] = handler;
}
},
//删除事件处理函数
removeHandler: function(element, type, handler){
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
}else if(element.detachEvent){
element.detachEvent('on' + type, handler);
}else{
element['on' + type] = null;
}
}
};

至此,核心功能已基本实现,整体逻辑并不复杂。只要理解其核心原理,后续的具体编码工作便水到渠成。

至于点击登录按钮触发的具体业务逻辑,此处不再赘述,只需为其绑定相应的事件处理函数即可。

完整源码(代码规范性有待优化)如下:


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>遮罩层效果</title>
<style type="text/css">
*{margin:0;padding:0;}
body{background: #ccc;font-family: "微软雅黑";height:2000px;/*用于测试*/}
.clearfix:after,
.clearfix:before{content: "";display: block;}
.clearfix{clear: both;visibility: hidden;}
img{border: 0;}
#header{width:100%;height:60px;line-height:60px;background: #000;}
#header a{display: block;width:60px;height:60px;color:#fff;text-decoration: none;font-size:15px;background:#c9394a;text-align: center;float: right;margin-right:138px;}
#login{position:fixed;width:400px;height:400px;background:#fff;z-index: 1001;}
.title{height:50px;background: #c9394a;line-height: 50px;}
.title span{display:inline-block;color:#fff;padding-left:20px;}
.title a{display: block;float:right;background: url(close.png) no-repeat center;width: 30px;height:30px;padding:20px 20px 0 0;}
.login_content form{padding-top:40px;width:340px;margin: 0 auto;}
.inp_group{margin-bottom:30px;}
#username{
background: url(sprite.png) no-repeat 0 0;
}
#passwd{
background: url(sprite.png) no-repeat 0 -46px;
}
input[type=password],input[type="text"]{
width:272px;height:40px;
outline: none;
padding-left:48px;
border: 1px solid #000;
font-size:15px;
}
input[type=button]{
width:318px;
height:38px;
margin:0 auto;
border:1px solid #f00000;
background-color:#f00000;
color:#fff;
font-size:15px;
outline:none;
cursor:pointer;
transition:all 1s;
}
input[type=button]:hover{
background:#ff0000;
border:1px solid #ff0000;
}
#mask{
background: #000;
opacity: .6;
filter:alpha(opacity=60);
position:absolute;
left:0;
top:0;
width:100%;
height:1000px;/*动态获取,这里设置高度是为了测试*/
z-index:1000;
}
</style>
<script type="text/javascript" src="base.js"></script>
<script type="text/javascript">
function popLogin(){
//获取页面的高度和宽度
var pageHeight = document.documentElement.scrollHeight;
var pageWidth = document.documentElement.scrollWidth;
//可视区域的高度和宽度
var clientHeight = document.documentElement.clientHeight;

//创建遮罩层节点
var oMask = document.createElement('div');
oMask.id = 'mask';
oMask.style.width = pageWidth + 'px';
oMask.style.height = pageHeight + 'px';
document.body.appendChild(oMask);
//创建登录节点
var oLogin = document.createElement('div');
oLogin.id = 'login';
oLogin.innerHTML = '<div class="title"><span>登录</span><a href="javascript:;" id="close"></a></div><div class="login_content"><form method="post" action="?"><div class="inp_group"><input type="text" name="username" id="username" placeholder="请输入登录邮箱"></div><div class="inp_group"><input type="password" name="password" id="passwd" placeholder="请输入密码"></div><input type="button" value="登录"></form></div>';
document.body.appendChild(oLogin);
var loginWidth = oLogin.offsetWidth;
var loginHeight = oLogin.offsetHeight;
console.log(clientHeight);
oLogin.style.left = (pageWidth - loginWidth) / 2 + 'px';
oLogin.style.top = ( clientHeight- loginHeight) / 2 + 'px';
var oClose = document.getElementById('close');
EventUtil.addHandler(oClose, 'click', function(){
document.body.removeChild(oMask);
document.body.removeChild(oLogin);
});
EventUtil.addHandler(oMask, 'click', function(){
document.body.removeChild(oMask);
document.body.removeChild(oLogin);
});
}
window.onload = function(){
var oLoginBtn = document.getElementById('login_btn');
EventUtil.addHandler(oLoginBtn, "click", popLogin);
};
</script>
</head>
<body>
<div id="header">
<a href="javascript:;" id="login_btn">登录</a>
</div>
<!--<div id="mask"></div>-->
<!--<div id="login">
<div class="title">
<span>登录</span>
<a href="javascript:;"></a>
</div>
<div class="login_content">
<form method="post" action="?">
<div class="inp_group">
<input type="text" name="username" id="username" placeholder="请输入登录邮箱">
</div>
<div class="inp_group">
<input type="password" name="password" id="passwd" placeholder="请输入密码">
</div>
<input type="button" value="登录">
</form>
</div>
</div>-->
</body>
</html>

代码展示完毕。本文内容如有不足之处,恳请读者批评指正。同时感谢大家一直以来的支持,祝各位元旦快乐。

作者最新文章