弹出层和弹窗相似但是并不相同;弹窗和弹出层都是由用户触发的显示提示信息的弹出面板;但是弹窗只是显示一些信息,没有太多的复杂的交互事件;而弹层类似一个整个页面,可以实现页面的所有功能;
现在前端弹层使用的很频繁,如支付宝支付弹层等…所以掌握弹层是一个很重要的技能。如果只是简单的隐藏和切换,当然就不必说,我要说的html+animate+es6实现弹层;
html弹层结构:
<main class="main"> <header class="head flex-center gray-theme">This is Header</header> <section class="body flex-center"> <ul class="btn-list flex-center btn-group"> <li class="btn-box"><span class="btn inline-flex-center" data-position="top">上弹层</span></li> <li class="btn-box"><span class="btn inline-flex-center" data-position="right">右弹层</span></li> <li class="btn-box"><span class="btn inline-flex-center" data-position="bottom">下弹层</span></li> <li class="btn-box"><span class="btn inline-flex-center" data-position="left">左弹层</span></li> </ul> </section> <footer class="foot flex-center gray-theme">This is Footer</footer> <!-- popup --> <section class="popup flex-center hide hidden"> <section class="popup-bg"></section> <section class="popup-wrapper"> <header class="title head flex-center"></header> <section class="container body flex-center"></section> <footer class="btn-wrapper foot flex-center"> <ul class="btn-list flex-center"> <li class="btn-box"><span class="btn cancel inline-flex-center">取消</span></li> <li class="btn-box"><span class="btn confirm inline-flex-center">确认</span></li> </ul> </footer> </section> </section> </main>
css代码:
@mixin slide-top{ 0%{ -webkit-transform: translate3d(0, -400%, 0); -moz-transform: translate3d(0, -400%, 0); -ms-transform: translate3d(0, -400%, 0); -o-transform: translate3d(0, -400%, 0); transform: translate3d(0, -400%, 0); } 100%{ -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes slideTop{ @include slide-top; } @-webkit-keyframes slideTop{ @include slide-top; } @mixin slide-top-hide{ 0%{ -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } 100%{ -webkit-transform: translate3d(0, -400%, 0); -moz-transform: translate3d(0, -400%, 0); -ms-transform: translate3d(0, -400%, 0); -o-transform: translate3d(0, -400%, 0); transform: translate3d(0, -400%, 0); } } @keyframes slideTopHide{ @include slide-top-hide; } @-webkit-keyframes slideTopHide{ @include slide-top-hide; } @mixin slide-right{ 0%{ -webkit-transform: translate3d(400%, 0, 0); -moz-transform: translate3d(400%, 0, 0); -ms-transform: translate3d(400%, 0, 0); -o-transform: translate3d(400%, 0, 0); transform: translate3d(400%, 0, 0); } 100%{ -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes slideRight{ @include slide-right; } @-webkit-keyframes slideRight{ @include slide-right; } @mixin slide-right-hide{ 0%{ -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } 100%{ -webkit-transform: translate3d(400%, 0, 0); -moz-transform: translate3d(400%, 0, 0); -ms-transform: translate3d(400%, 0, 0); -o-transform: translate3d(400%, 0, 0); transform: translate3d(400%, 0, 0); } } @keyframes slideRightHide{ @include slide-right-hide; } @-webkit-keyframes slideRightHide{ @include slide-right-hide; } @mixin slide-bottom{ 0%{ -webkit-transform: translate3d(0, 400%, 0); -moz-transform: translate3d(0, 400%, 0); -ms-transform: translate3d(0, 400%, 0); -o-transform: translate3d(0, 400%, 0); transform: translate3d(0, 400%, 0); } 100%{ -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes slideBottom{ @include slide-bottom; } @-webkit-keyframes slideBottom{ @include slide-bottom; } @mixin slide-bottom-hide{ 0%{ -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } 100%{ -webkit-transform: translate3d(0, 400%, 0); -moz-transform: translate3d(0, 400%, 0); -ms-transform: translate3d(0, 400%, 0); -o-transform: translate3d(0, 400%, 0); transform: translate3d(0, 400%, 0); } } @keyframes slideBottomHide{ @include slide-bottom-hide; } @-webkit-keyframes slideBottomHide{ @include slide-bottom-hide; } @mixin slide-left{ 0%{ -webkit-transform: translate3d(-400%, 0, 0); -moz-transform: translate3d(-400%, 0, 0); -ms-transform: translate3d(-400%, 0, 0); -o-transform: translate3d(-400%, 0, 0); transform: translate3d(-400%, 0, 0); } 100%{ -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes slideLeft{ @include slide-left; } @-webkit-keyframes slideLeft{ @include slide-left; } @mixin slide-left-hide{ 0%{ -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } 100%{ -webkit-transform: translate3d(-400%, 0, 0); -moz-transform: translate3d(-400%, 0, 0); -ms-transform: translate3d(-400%, 0, 0); -o-transform: translate3d(-400%, 0, 0); transform: translate3d(-400%, 0, 0); } } @keyframes slideLeftHide{ @include slide-left-hide; } @-webkit-keyframes slideLeftHide{ @include slide-left-hide; } @mixin popup-hide{ 0%{ z-index: 99999; opacity: 1; } 100%{ z-index: -1; opacity: 0; } } @keyframes popupHide{ @include popup-hide; } @-webkit-keyframes popupHide{ @include popup-hide; } .popup{ position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; opacity: 0; .popup-bg{ position: absolute; top: 0; left: 0; background: rgba(0,0,0, 0.5); width: 100%; height: 100%; z-index: 1; } .popup-wrapper{ position: relative; width: 70%; height: 70%; margin: auto; background: #fff; border-radius: 5%; z-index: 100; } &.hidden{ display: none; } &.show{ z-index: 99999; opacity: 1; &.top{ .popup-wrapper{ -webkit-animation: slideTop 0.6s linear forwards; -moz-animation: slideTop 0.6s linear forwards; -ms-animation: slideTop 0.6s linear forwards; -o-animation: slideTop 0.6s linear forwards; animation: slideTop 0.6s linear forwards; } } &.right{ .popup-wrapper{ -webkit-animation: slideRight 0.6s linear forwards; -moz-animation: slideRight 0.6s linear forwards; -ms-animation: slideRight 0.6s linear forwards; -o-animation: slideRight 0.6s linear forwards; animation: slideRight 0.6s linear forwards; } } &.bottom{ .popup-wrapper{ -webkit-animation: slideBottom 0.6s linear forwards; -moz-animation: slideBottom 0.6s linear forwards; -ms-animation: slideBottom 0.6s linear forwards; -o-animation: slideBottom 0.6s linear forwards; animation: slideBottom 0.6s linear forwards; } } &.left{ .popup-wrapper{ -webkit-animation: slideLeft 0.6s linear forwards; -moz-animation: slideLeft 0.6s linear forwards; -ms-animation: slideLeft 0.6s linear forwards; -o-animation: slideLeft 0.6s linear forwards; animation: slideLeft 0.6s linear forwards; } } } &.hide{ -webkit-animation: popupHide 0.7s linear forwards; -moz-animation: popupHide 0.7s linear forwards; -ms-animation: popupHide 0.7s linear forwards; -o-animation: popupHide 0.7s linear forwards; animation: popupHide 0.7s linear forwards; &.top{ .popup-wrapper{ -webkit-animation: slideTopHide 0.6s linear forwards; -moz-animation: slideTopHide 0.6s linear forwards; -ms-animation: slideTopHide 0.6s linear forwards; -o-animation: slideTopHide 0.6s linear forwards; animation: slideTopHide 0.6s linear forwards; } } &.right{ .popup-wrapper{ -webkit-animation: slideRightHide 0.6s linear forwards; -moz-animation: slideRightHide 0.6s linear forwards; -ms-animation: slideRightHide 0.6s linear forwards; -o-animation: slideRightHide 0.6s linear forwards; animation: slideRightHide 0.6s linear forwards; } } &.bottom{ .popup-wrapper{ -webkit-animation: slideBottomHide 0.6s linear forwards; -moz-animation: slideBottomHide 0.6s linear forwards; -ms-animation: slideBottomHide 0.6s linear forwards; -o-animation: slideBottomHide 0.6s linear forwards; animation: slideBottomHide 0.6s linear forwards; } } &.left{ .popup-wrapper{ -webkit-animation: slideLeftHide 0.6s linear forwards; -moz-animation: slideLeftHide 0.6s linear forwards; -ms-animation: slideLeftHide 0.6s linear forwards; -o-animation: slideLeftHide 0.6s linear forwards; animation: slideLeftHide 0.6s linear forwards; } } } } html, body, .main{ width: 100%; height: 100%; overflow: hidden; } .head, .body, .foot{ width: 100%; } .head, .foot{ height: 15%; } .body{ height: 70%; } .gray-theme{ background: #333; color: #fff; } .btn-list{ width: 40%; min-width: 270px; height: 38px; .btn-box{ width: 22%; height: 100%; padding-right: 4%; &:last-child{ padding-right: 0; } } } .btn{ line-height: 1em; width: 100%; height: 100%; border-radius: 10%; font-size: 16px; background: green; color: #ff0; text-align: center; vertical-align: middle; cursor: pointer; }
js代码:
class PopupComponent { constructor() { this.btnGroupEl = document.getElementsByClassName("btn-group")[0]; this.popupEl = document.getElementsByClassName("popup")[0]; this.popupBGEl = this.popupEl.querySelector(".popup-bg"); this.popupTitleEl = this.popupEl.querySelector(".popup-wrapper .title"); this.popupBodyEl = this.popupEl.querySelector(".popup-wrapper .body"); this.cancelBtnEl = this.popupEl.querySelector(".popup-wrapper .btn.cancel"); this.confirmBtnEl = this.popupEl.querySelector(".popup-wrapper .btn.confirm"); this.popupElClasslist = this.popupEl.classList; this.LEGVALS = ["top", "right", "bottom", "left"]; this.detaultPosition = ""; this.position = ""; this.SHOWCLASSNAME = "show"; this.HIDECLASSNAME = "hide"; this.HIDDENCLASSNAME = "hidden"; } /** * 给弹窗的标题和主体添加内容 * @param Object contentObj 传递的对象 */ setContentForPopup(contentObj = {'title':'title', 'body': 'body'}) { try{ if (!TB.isObject(contentObj)) { throw new Error("The param of setContentForPopup function error!"); } let value; for (let prop in contentObj) { if (!contentObj.hasOwnProperty(prop)) { continue; } if (prop === 'title') { value = contentObj[prop]; this.popupTitleEl.innerText = value; } if (prop === 'body') { value = contentObj[prop]; this.popupBodyEl.innerText = value; } } } catch (e) { console.log("Popup element is not exist!"); console.error(e); } } /** * 删除弹窗的类名 * @return void */ deletePopupPreviousClassName() { if (this.HIDDENCLASSNAME && KB.checkType.isString(this.HIDDENCLASSNAME)) { this.popupElClasslist.remove(this.HIDDENCLASSNAME); } if (this.detaultPosition && KB.checkType.isString(this.detaultPosition)) { this.popupElClasslist.remove(this.detaultPosition); } this.detaultPosition = this.position; } /** * 弹窗隐藏 * @return void */ popupHide() { if (this.popupElClasslist.contains(this.SHOWCLASSNAME)) { this.popupElClasslist.remove(this.SHOWCLASSNAME); this.popupElClasslist.add(this.HIDECLASSNAME); } } /** * 弹窗显示 * @return void */ popupShow() { this.deletePopupPreviousClassName(); if (this.popupElClasslist.contains(this.HIDECLASSNAME)) { this.popupElClasslist.remove(this.HIDECLASSNAME); this.popupElClasslist.add(this.SHOWCLASSNAME); this.popupElClasslist.add(this.position); } this.setContentForPopup({ 'title': this.position + ' title', 'body': this.position + ' body', }); } /** * 按钮容器的点击事件 * @param Object e 点击的事件event * @return void */ btnGroupClickEvent(e) { let btnEl = e.target || e.srcElement; if (!TB.isElement(btnEl)) { throw new Error("Get btn element error!"); } this.position = btnEl.getAttribute("data-position"); if (!TB.isString(this.position) || (this.LEGVALS.indexOf(this.position) < 0)) { throw new Error("Can not get position value from btn element!"); } this.popupShow(); } /** * 给DOM元素添加点击事件 * @param Object elem 添加点击事件的dom元素 * @param Function fn 触发事件调用的回调函数 */ addClickEventFormElem(elem, fn) { TB.addHandler.call(this, elem, 'click', fn, false); } /** * 初始化函数 * @return void */ init() { this.addClickEventFormElem(this.btnGroupEl, this.btnGroupClickEvent); this.addClickEventFormElem(this.cancelBtnEl, this.popupHide); this.addClickEventFormElem(this.confirmBtnEl, this.popupHide); } } let popupComponent = new PopupComponent(); popupComponent.init();
TB.addHandler:
/* * 给DOM元素添加事件 * @param void * @return callback function 回调函数 * */ function addHandler(elem, type, callback, useCapture) { var checkType = checkArgumentType(), _document = document, _callback = checkType.isFunction(callback)"on" + type, function(e){ _callback.apply(_self, [e]); }); } } else { addHandler = function(elem, type, callback, useCapture) { elem["on" + type] = function(e) { _callback.call(_self, e); }; } } addHandler(elem, type, callback, useCapture); }
首先说一下弹窗的DOM结构:
在外层一般是绝对定位,并使用flex布局使得内容居中;它的直接子元素一般有两个,黑色背景层和内容容器;如图所示:
样式的动画相信前端的同学一般都知道怎么做;但是有一点要注意,不要试图使用display来实现动画;
我使用的解决的办法是首先
动画的显示隐藏使用的z-index和opacity;但是这样存在开始时,弹窗会缓缓隐藏,那么我们可以用一个类表示display: none;点击显示弹层时,移除该类即可;
对于js没什么好说的,无非是操作类名;但是有一点要注意事件注册和this的指向;
注意我的addHandler函数,该函数只会判断一次浏览器的环境,不需要反复的判断浏览器的环境;
在btnGroupClickEvent函数中this是指向PopupComponent类,而不是事件的event;所以addHandler函数中首先保存this的指向,然后使用call或者apply改变this的指向
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
js,弹出层
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]