按照国际惯例先放效果图
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>demo</title> <link rel="stylesheet" href="./msg.css"> <style> #pop { border: 0 none; color: #fff; outline: none; padding: 10px 20px; font-size: 18px; background: #2594f0; cursor: pointer; } #pop:active { background: blue; } </style> </head> <body> <button id="pop">弹个框</button> <!-- <div class="msg__wrap"> <div class="msg-header"> <span>确认删除</span> <span class="msg-header-close-button">×</span> </div> <div class="msg-body"> <div class="msg-body-icon"> <div class="msg-body-icon-wrong"></div> </div> <div class="msg-body-content">是否删除</div> </div> <div class="msg-footer"> <button class="msg-footer-btn msg-footer-cancel-button">算了吧</button> <button class="msg-footer-btn msg-footer-confirm-button">好的</button> </div> </div> --> <script src="./msg.js"></script> <script type="text/javascript"> document.querySelector('#pop').addEventListener('click', function() { new $Msg({ content: '贤者模式马上就过去了...真的要清空吗?<span style="color: orange;">~~~</span>', confirm:function(e){ console.log("confirm"); console.log(this); }, cancel:function(e){ console.log("cancel"); console.log(this); }, contentStyle:{ fontSize:"20px", background:"lightgreen" }, useHTML:true }); }); </script> </body> </html>
msg.css
/* 弹出框最外层 */ .msg__wrap { position: fixed; top: 50%; left: 50%; z-index: 10; transition: all .3s; transform: translate(-50%, -50%) scale(0, 0); max-width: 50%; background: #fff; box-shadow: 0 0 10px #eee; font-size: 10px; } /* 弹出框头部 */ .msg__wrap .msg-header { padding: 10px 10px 0 10px; font-size: 1.8em; } .msg__wrap .msg-header .msg-header-close-button { float: right; cursor: pointer; } /* 弹出框中部 */ .msg__wrap .msg-body { padding: 10px 10px 10px 10px; display: flex; } /* 图标 */ .msg__wrap .msg-body .msg-body-icon{ width: 80px; } .msg__wrap .msg-body .msg-body-icon div{ width: 45px; height: 45px; margin: 0 auto; line-height: 45px; color: #fff; border-radius: 50% 50%; font-size: 2em; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-success{ background: #32a323; text-align: center; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-success::after{ content: "成"; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-wrong{ background: #ff8080; text-align: center; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-wrong::after{ content: "误"; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-info{ background: #80b7ff; text-align: center; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-info::after{ content: "注"; } /* 内容 */ .msg__wrap .msg-body .msg-body-content{ min-width: 200px; font-size: 1.5em; word-break: break-all; display: flex; align-items: center; padding-left: 10px; box-sizing: border-box; } /* 弹出框底部 */ .msg__wrap .msg-footer { padding: 0 10px 10px 10px; display: flex; flex-direction: row-reverse; } .msg__wrap .msg-footer .msg-footer-btn { width: 50px; height: 30px; border: 0 none; color: #fff; outline: none; font-size: 1em; border-radius: 2px; margin-left: 5px; cursor: pointer; } .msg__wrap .msg-footer .msg-footer-cancel-button{ background-color: #ff3b3b; } .msg__wrap .msg-footer .msg-footer-cancel-button:active{ background-color: #ff6f6f; } .msg__wrap .msg-footer .msg-footer-confirm-button{ background-color: #4896f0; } .msg__wrap .msg-footer .msg-footer-confirm-button:active{ background-color: #1d5fac; } /* 遮罩层 */ .msg__overlay { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 5; background-color: rgba(0, 0, 0, .4); transition: all .3s; opacity: 0; }
msg.js
//放入自执行的匿名函数,避免污染全局作用域 //将window和document作为参数传入,可以直接在内部获取,不用再去外部找,性能更优 (function(window,document){ //构造函数 let Msg=function(options){ //初始化一个弹出框 this._init(options); } //初始化一个弹出框 Msg.prototype._init=function({content="",confirm=null,cancel=null,useHTML=false,contentStyle={},contentFontSize="1.5em"}){ this.content=content; this.confirm=confirm; this.cancel=cancel; this.useHTML=useHTML; this.contentStyle=contentStyle; this.contentFontSize=contentFontSize; //生成DOM元素 this._createElement(); //绑定事件 this._bind([this._el,this._overlay]); //显示 this._show([this._el,this._overlay]); } //生成DOM元素 Msg.prototype._createElement=function(){ let wrap=document.createElement("div"); wrap.className="msg__wrap"; //换行前加上转义 wrap.innerHTML='<div class="msg-header"> <span>确认删除</span> <span class="msg-header-close-button">×</span> </div> <div class="msg-body"> <div class="msg-body-icon"> <div class="msg-body-icon-info"></div> </div> <div class="msg-body-content"></div> </div> <div class="msg-footer"> <button class="msg-footer-btn msg-footer-cancel-button">算了吧</button> <button class="msg-footer-btn msg-footer-confirm-button">好的</button> </div>'; //根据传入的参数控制content样式 let contentDom=wrap.querySelector(".msg-body .msg-body-content"); //用解构赋值来合并对象 const contentStyle={ contentFontSize:this.contentFontSize, ...this.contentStyle } for(let i in contentStyle){ //如果是自身的属性 if(contentStyle.hasOwnProperty(i)){ //style[i]==>style.i //i是属性名,contentStyle[i]是属性值 contentDom.style[i]=contentStyle[i]; } } //如果使用html if(this.useHTML){ contentDom.innerHTML=this.content; }else{ contentDom.innerText=this.content; } let overlay=document.createElement("div"); overlay.className="msg__overlay"; this._el=wrap; this._overlay=overlay; } //显示 Msg.prototype._show=function([el,overlay]){ document.body.appendChild(el); document.body.appendChild(overlay); //设置动画效果显示 //延迟实现异步效果 setTimeout(function(){ el.style.transform='translate(-50%, -50%) scale(1, 1)'; overlay.style.opacity=1; }); } //绑定事件 Msg.prototype._bind=function([el,overlay]){ const _this=this; //隐藏事件 const hideMsg=function(){ el.style.transform='translate(-50%, -50%) scale(0, 0)'; overlay.style.opacity=0; //动画结束后移除元素(css里设置的动画时间是300ms) setTimeout(function(){ document.body.removeChild(el); document.body.removeChild(overlay); },300); } //取消事件 const cancel=function(e){ //如果传入了回调,则执行回调,参数是e _this.cancel && _this.cancel.call(this._cancel,e); hideMsg(); } //确认事件 const confirm=function(e){ _this.confirm && _this.confirm.call(_this.confirm,e); hideMsg(); } //点击遮罩 overlay.addEventListener("click",hideMsg); //点击右上角叉叉 el.querySelector(".msg-header .msg-header-close-button").addEventListener("click",hideMsg); //点击取消按钮 el.querySelector(".msg-footer .msg-footer-cancel-button").addEventListener("click",cancel); //点击确认按钮 el.querySelector(".msg-footer .msg-footer-confirm-button").addEventListener("click",confirm); } //挂到window上可全局访问 window.$Msg=Msg; })(window,document);