javascript實現(xiàn)彈出層效果
彈出層和彈窗相似但是并不相同;彈窗和彈出層都是由用戶觸發(fā)的顯示提示信息的彈出面板;但是彈窗只是顯示一些信息,沒有太多的復雜的交互事件;而彈層類似一個整個頁面,可以實現(xiàn)頁面的所有功能;
現(xiàn)在前端彈層使用的很頻繁,如支付寶支付彈層等…所以掌握彈層是一個很重要的技能。如果只是簡單的隱藏和切換,當然就不必說,我要說的html+animate+es6實現(xiàn)彈層;




html彈層結(jié)構(gòu):
<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";
}
/**
* 給彈窗的標題和主體添加內(nèi)容
* @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 觸發(fā)事件調(diào)用的回調(diào)函數(shù)
*/
addClickEventFormElem(elem, fn) {
TB.addHandler.call(this, elem, 'click', fn, false);
}
/**
* 初始化函數(shù)
* @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 回調(diào)函數(shù)
* */
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結(jié)構(gòu):
在外層一般是絕對定位,并使用flex布局使得內(nèi)容居中;它的直接子元素一般有兩個,黑色背景層和內(nèi)容容器;如圖所示:

樣式的動畫相信前端的同學一般都知道怎么做;但是有一點要注意,不要試圖使用display來實現(xiàn)動畫;
我使用的解決的辦法是首先
動畫的顯示隱藏使用的z-index和opacity;但是這樣存在開始時,彈窗會緩緩隱藏,那么我們可以用一個類表示display: none;點擊顯示彈層時,移除該類即可;
對于js沒什么好說的,無非是操作類名;但是有一點要注意事件注冊和this的指向;
注意我的addHandler函數(shù),該函數(shù)只會判斷一次瀏覽器的環(huán)境,不需要反復的判斷瀏覽器的環(huán)境;
在btnGroupClickEvent函數(shù)中this是指向PopupComponent類,而不是事件的event;所以addHandler函數(shù)中首先保存this的指向,然后使用call或者apply改變this的指向
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
JS中判斷字符串中出現(xiàn)次數(shù)最多的字符及出現(xiàn)的次數(shù)的簡單實例
下面小編就為大家?guī)硪黄狫S中判斷字符串中出現(xiàn)次數(shù)最多的字符及出現(xiàn)的次數(shù)的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06
Ajax 文件上傳進度監(jiān)聽之upload.onprogress案例詳解
這篇文章主要介紹了Ajax 文件上傳進度監(jiān)聽之upload.onprogress案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-09-09
js實現(xiàn)仿愛微網(wǎng)兩級導航菜單效果代碼
這篇文章主要介紹了js實現(xiàn)仿愛微網(wǎng)兩級導航菜單效果代碼,通過javascript自定義函數(shù)結(jié)合鼠標點擊事件實現(xiàn)tab切換的功能,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08

