javascript实现弹出层效果

弹出层和弹窗相似但是并不相同;弹窗和弹出层都是由用户触发的显示提示信息的弹出面板;但是弹窗只是显示一些信息,没有太多的复杂的交互事件;而弹层类似一个整个页面,可以实现页面的所有功能;

现在前端弹层使用的很频繁,如支付宝支付弹层等…所以掌握弹层是一个很重要的技能。如果只是简单的隐藏和切换,当然就不必说,我要说的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)? callback:function(){},

_self = this;

if (!checkType.isElement(elem) || !checkType.isString(type)) {

return;

}

if (_document.addEventListener) {

addHandler = function(elem, type, callback, useCapture) {

elem.addEventListener(type, function(e) {

_callback.call(_self, e);

}, useCapture || false);

}

} else if (_document.attachEvent) {

addHandler = function(elem, type, callback, useCapture) {

elem.attachEvent("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的指向

以上是 javascript实现弹出层效果 的全部内容, 来源链接: utcz.com/z/341847.html

回到顶部