目标
实现简易的js弹出框.为了简单灵活的在小项目中使用.
实现思路
研究bootstrap的弹出框效果后,认为层级示意图如下:
层说明
弹出层分为三层.最底层的遮罩层,覆盖在浏览器视口上.它之上是弹出层父级,这个层完全透明,并且与遮罩层重合.最上层是弹出层,它的活动范围在其父层的范围内.
- 弹出时,隐藏body的滚动条
- 遮罩层位于body直属,固定定位,大小与视口相等.不必有dom,在每次弹出时,由js直接生成.
- 弹出层父级位于body直属,透明隐藏,大小同遮罩层,自动垂直滚动条.位于遮罩层与弹出层之间.
- 弹出层是一个自定义的DOM,位于最上层.
- 每个弹出层可做一个模板,放在templete标记内.
html结构
建议的弹出层的HTML结构
<div class="msgbox-content"> <div class="msgbox-header"><h3 class="msgbox-title">标题</h3><a class="msgbox-close">×</a></div> <div class="msgbox-body">弹出框内容</div> <div class="msgbox-footer"><a class="btn lg">确定</a><a class="btn lg">取消</a></div> </div>
位置
弹出层父级使用flex布局,可简洁的实现在9种位置上弹出.
实现功能
jq插件方式,模态框和倒计时消失框,9种位置弹出,按esc关闭,点击背景关闭,支持绑定显示前后和关闭后事件,*定义弹出框
使用方式
// alert框 $.msgboxalert(\'alert框,默认2秒后关闭.\') // 倒计时间3秒关闭 $.msgboxalert(\'alert框,默认2秒后关闭.\',3000) // 显示在右下方 $.msgboxalert(\'alert框,默认2秒后关闭.\',3000,\'br\') // 模态框 let config={ escClose:true } $(\'#msg_box\').modal(config);
js
1 $.extend({ 2 // alert框 {msg:要提示的信息,[timeout]:关闭时间(2000毫秒),[location]:位置(tl,tm,tr,ml,mr,bl,bm,br)} 3 msgboxalert: function (msg, timeout, location) 4 { 5 $(\'body .msgbox-modal\').remove(); 6 // alert组件弹出层Dom 7 let dom = \'<div class="msgbox-modal $location"><div class="msgbox-alert">$msg</div></div>\'; 8 dom = dom.replace("$msg", msg || \'\'); 9 dom = dom.replace("$location", location || \'\'); 10 // 11 $(\'body\').append(dom); 12 // 自动消失 13 setTimeout(() => 14 { 15 $(\'body .msgbox-modal\').remove(); 16 }, timeout || 2000) 17 }, 18 // 清除所有弹出框,还原body滚动条状态 {closeE:fun} 19 msgboxClear: function (closeE) 20 { 21 $(\'body\').find(\'.msgbox-shadow,.msgbox-modal\').remove(); 22 $(\'body\').removeClass(\'overflowhide\'); 23 if (typeof closeE == \'function\') 24 { 25 closeE(); 26 } 27 } 28 }); 29 $.fn.extend({ 30 // 模态框 {beforeShow:fun,afterShow:fun,afterClose:fun,escClose:false,backClose:false,location:\'\'} 31 modal: function (config) 32 { 33 //=== 弹出层父级类名:为方便引用() 34 let modalClsName = \'msgbox-modal\'; 35 //=== init config 36 let cfg = {}; 37 if (config) 38 { 39 // 显示之前执行 40 cfg.beforeShow = config.beforeShow || null; 41 // 显示后执行 42 cfg.afterShow = config.afterShow || null; 43 // 关闭后执行 44 cfg.afterClose = config.afterClose || null; 45 // 按esc关闭 46 cfg.escClose = config.escClose || false; 47 // 点击背景(弹出层父级)关闭 48 cfg.backClose = config.backClose || false; 49 // 位置 50 cfg.location = config.location || \'\'; 51 } 52 53 //=== 54 // body禁用滚动条 55 // 删除旧的遮罩层 56 $(\'body\').addClass(\'overflowhide\').find(\'.msgbox-shadow,.msgbox-modal\').remove(); 57 58 //=== 弹出层准备: dom生成,相关事件执行 59 // 将弹出层包含在弹出层父级DOM中 60 let modal = $(\'<div class="\' + modalClsName + \' \' + cfg.location + \'" tabindex="-1"></div>\'); 61 modal.append($(this)); 62 // x按钮事件:点击关闭弹出框 63 modal.find(\'.msgbox-close\').on(\'click\', function () 64 { 65 $.msgboxClear(cfg.afterClose); 66 }) 67 // 按ESC关闭 68 if (cfg.escClose == true) 69 { 70 modal.on("keyup", function (event) 71 { 72 //alert(event.target.className + event.which ); 73 if (event.which != 27 || event.target.className.indexOf(modalClsName)==-1) 74 return; 75 $.msgboxClear(cfg.afterClose); 76 }); 77 } 78 // 点击背景关闭 79 if (cfg.backClose == true) 80 { 81 modal.on(\'click\', function (event) 82 { 83 if (event.target.className.indexOf(modalClsName) == -1) 84 return; 85 $.msgboxClear(cfg.afterClose); 86 }); 87 } 88 // 显示之前执行 89 if (typeof cfg.beforeShow == \'function\') 90 { 91 cfg.beforeShow($(this)); 92 } 93 // 显示遮罩 94 $(\'body\').append(\'<div class="msgbox-shadow"></div>\'); 95 // 显示弹出框 96 $(\'body\').append(modal); 97 // 让弹出层父级获得焦点 98 modal.focus(); 99 // 显示之后执行 100 if (typeof cfg.afterShow == \'function\') 101 { 102 cfg.afterShow($(this)); 103 } 104 } 105 })
css
//=== 关键部分css样式
// 弹出框时,body设为无滚动条 .overflowhide { overflow: hidden; } // 遮罩层/ .msgbox-shadow { position: fixed; left: 0; top: 0; right: 0; bottom: 0; // 黑色背景,透明度 opacity: .4; background-color: #000; // 层级位于弹出层父级之下 z-index: 10000; } // 弹出层父级 .msgbox-modal { // 使用flex布局,默认弹出层水平垂直居中 display: flex; justify-content: center; align-items: center; // 固定定位 position: fixed; left: 0; top: 0; right: 0; bottom: 0; overflow-x: hidden; overflow-y: auto; // 在遮罩层之上 z-index: 10001; }
详细示例代码,修改后的
https://github.com/mirrortom/webcoms/tree/master/msgbox