完成样式示例
使用技术栈: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>
复制
制作不易,这是我的第一个帖子,部分代码还是有些繁琐,如果对您有帮助还请多多支持,如有更好的建议可以在评论中提出,感谢大家!