完成样式示例
使用技术栈:jquery、javaScript、HTML/CSS
一、基础版面
模态框的版面无非就是遮罩层、悬浮在遮罩上的盒子、标题、内容这四部分,所以基础的html结构很好做:
<!-- 模态框 -->
<div class="modal">
<!-- 弹窗 -->
<div class="modal-content">
<div class="modal_title">
<span class="close-btn">×</span>
<p class="speaking_title">警告</p>
</div>
<!-- 提示文本区域 -->
<p class="warning_text"></p>
<textarea class="input_textarea"></textarea>
<!-- 按钮区域 -->
<div class="modal_btn">
<button class="close_speaking_button cancellation">取消</button>
<button class="close_speaking_button determine">确定</button>
<button class="close_speaking_button close">关闭</button>
</div>
</div>
</div>
如上,modal就是遮罩层,modal_content就是弹出框主体。当然遮罩层可以放在任意的位置,我个人是比较习惯把整个模态框都包住的。
模态框的样式都大差不差,这里只举例了百分比的弹出样式,大家可以根据需要自行调整局部样式,不是很难。
/* 全局默认 */
*{
margin: 0;
padding: 0;
list-style: none;
user-select: none;
}
/* 遮罩层 */
.modal {
display: none;
position: fixed;
z-index: 10000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
}
/* 模态框 */
.modal-content{
background-color: #fefefe;
margin: 10% auto;
padding: 20px;
width: 30%;
min-height: 150px;
height: auto;
border-radius: 10px;
border: 1px solid #888;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
animation-name: modalopen;
animation-duration: 0.2s;
}
/* 交互按钮(不重要) */
.open-btn-prompt,.open-btn-about,.open-btn-input{
display: block;
margin: 0 auto;
margin-top: 50px;
border: 1px solid #ccc;
width: 150px;
height: 40px;
border-radius: 5px;
}
/* 模态框标题 */
.speaking_title{
font-weight: bold;
font-size: 20px;
}
/* 模态框内容 */
.speaking_text,.warning_text{
line-height: 50px;
margin: 20px 0;
}
/* 关闭按钮 */
.close-btn {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
/* 关闭按钮样式 */
.close-btn:hover,
.close-btn:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
/* 模态框内部按钮样式 */
.modal_btn{
display: flex;
justify-content: flex-end;
}
/* 关闭按钮统一样式 */
.close_speaking_button{
display: block;
width: 70px;
height: 30px;
border: none;
border-radius: 3px;
background: #00bfff;
color: #fff;
margin-right: 10px;
}
/* hover样式 */
.close_speaking_button:hover,
.close_speaking_button:focus{
background: #43aaf3;
}
.close_speaking_button:active{
background: #00bfff;
}
.cancellation{
background: #ccc;
}
.cancellation:hover,
.cancellation:focus{
background: #bab8b8;
}
.cancellation:active{
background: #ccc;
}
/* 动画 */
@keyframes modalopen {
from {transform: scale(0)}
to {transform: scale(1)}
}
/* 输入框样式 */
.input_textarea{
width: 100% !important;
margin-bottom: 30px;
}
至此,大致的样式就已经出来了,接下来就是功能部分;
二、功能封装
模态框分为两部分,触发事件和回调参数;所以监听回调我们可以通过抛出一个Promise来获取到,具体代码如下:
modal_dialog.js
function showModal(type, title, message) {
return new Promise(function (resolve, reject) {
const modal = document.querySelector('.modal');
const titleElement = document.querySelector('.speaking_title');
const messageElement = document.querySelector('.warning_text');
$(".modal").fadeIn();
});
}
如上,定义了一个showModal函数,他接收三个参数:弹框类型、弹框标题、弹框内容;这样,一个基础的模态框函数就成功封装了,接下来就是样式的展示和控制;
三、模态框展示
我们拿到了模态框的type,那就可以基于type来动态渲染样式,具体实现逻辑如下(在showModal函数中):
// 设置模态框的内容
titleElement.textContent = title;
messageElement.textContent = message;
// 显示模态框
modal.style.display = 'block';
// 判断输入框类型
$('.close').css("display", "none");
$('.cancellation').css("display", "none");
$('.determine').css("display", "none");
$(".input_textarea").css("display", "none");
if (type === 'prompt') {
$('.cancellation').css("display", "block");
$('.determine').css("display", "block");
} else if (type === 'about') {
$('.close').css("display", "block");
} else if (type === 'input') {
$('.cancellation').css("display", "block");
$('.determine').css("display", "block");
$(".input_textarea").css("display", "block");
}
如上,我们渲染了接收到的标题和内容,并在展示模态框的时候通过type参数判断展示模态框的类型,并分别渲染;至此,模态框的展示逻辑已经全部完毕;
四、监听事件
模态框内有很多交互事件,分别是取消、确认、右上角的叉号以及点击空白区域等,这些事件执行的逻辑是不一样的,我们在函数中注册这三个按钮的点击事件,并进行不同的回调调用,就可以动态的返回结果啦!具体实现代码如下(在showModal函数中):
// 点击确认按钮
$('.determine').click(function () {
$(".modal").fadeOut(function () {
if (type === 'input') {
resolve($(".input_textarea").val());
$(".input_textarea").val('');
} else {
resolve('confirmed');
}
});
});
// 点击取消按钮
$('.cancellation').click(function () {
$(".modal").fadeOut(function () {
reject('cancelled');
$(".input_textarea").val('');
});
});
// 点击关闭按钮
$('.close').click(function () {
$(".modal").fadeOut(function () {
resolve('confirmed');
});
});
// 点击关闭按钮或点击模态框外部区域时关闭模态框
const closeButton = document.querySelector('.close-btn');
window.onclick = function (event) {
if (event.target == modal || event.target == closeButton) {
$(".modal").fadeOut(function () {
if (type === 'prompt') {
reject('cancelled');
} else if (type === 'about') {
resolve('confirmed');
} else if (type === 'input') {
$(".input_textarea").val('');
}
});
}
};
至此,所有的交互事件也成功注册,但是我们会发现一个问题:每次触发事件,都会永久增加事件的触发次数,这对我们代码的运行是有隐患的。问题点就是由于事件处理程序没有正确地移除或重置,导致多个事件处理程序被绑定到同一个元素上。为了解决这个问题,可以在每次调用 showModal
之前,先移除之前的事件处理程序。可以使用 jQuery 的 off
方法来移除事件处理程序:
// 移除之前的事件处理程序
$('.determine').off('click');
$('.cancellation').off('click');
$('.close').off('click');
window.onclick = null
至此,我们就成功封装了一个基于jQuery实现的模态框及其全部的事件处理逻辑啦!在页面中调用方法如下:
modal_dialog.html
<!DOCTYPE html>
<html>
<head>
<title>模态框</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="./modal_dialog_模态框.css"/>
</head>
<body>
<button class="open-btn-prompt">提示模态框</button>
<button class="open-btn-about">询问模态框</button>
<button class="open-btn-input">输入模态框</button>
<!-- 模态框 -->
<div class="modal">
<div class="modal-content">
<div class="modal_title">
<span class="close-btn">×</span>
<p class="speaking_title">警告</p>
</div>
<!-- 提示文本区域 -->
<p class="warning_text"></p>
<textarea class="input_textarea"></textarea>
<!-- 按钮区域 -->
<div class="modal_btn">
<button class="close_speaking_button cancellation">取消</button>
<button class="close_speaking_button determine">确定</button>
<button class="close_speaking_button close">关闭</button>
</div>
</div>
</div>
<script src="./jq.js"></script>
<script src="./modal_dialog.js"></script>
<script>
// 提示操作
$(".open-btn-prompt").click(function () {
showModal('about', '提示', '加入成功')
.then(result => console.log('关闭', result))
});
// 询问操作
$(".open-btn-about").click(function () {
showModal('prompt', '询问', '确定添加?')
.then(result => {
showModal('about', '提示', '加入成功')
})
.catch(reason => console.log('取消', reason));
})
// 输入操作
$(".open-btn-input").click(function () {
showModal('input', '输入', '请输入内容')
.then(result => console.log('确定', result))
.catch(reason => console.log('取消', reason));
})
</script>
</body>
</html>
制作不易,这是我的第一个帖子,部分代码还是有些繁琐,如果对您有帮助还请多多支持,如有更好的建议可以在评论中提出,感谢大家!