javascript实现弹出层效果
弹出层和弹窗相似但是并不相同;弹窗和弹出层都是由用户触发的显示提示信息的弹出面板;但是弹窗只是显示一些信息,没有太多的复杂的交互事件;而弹层类似一个整个页面,可以实现页面的所有功能;
现在前端弹层使用的很频繁,如支付宝支付弹层等…所以掌握弹层是一个很重要的技能。如果只是简单的隐藏和切换,当然就不必说,我要说的html+animate+es6实现弹层;
html弹层结构:
ThisisHeader 上弹层 右弹层 下弹层 左弹层
css代码:
@mixinslide-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);
}
}
@keyframesslideTop{
@includeslide-top;
}
@-webkit-keyframesslideTop{
@includeslide-top;
}
@mixinslide-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);
}
}
@keyframesslideTopHide{
@includeslide-top-hide;
}
@-webkit-keyframesslideTopHide{
@includeslide-top-hide;
}
@mixinslide-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);
}
}
@keyframesslideRight{
@includeslide-right;
}
@-webkit-keyframesslideRight{
@includeslide-right;
}
@mixinslide-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);
}
}
@keyframesslideRightHide{
@includeslide-right-hide;
}
@-webkit-keyframesslideRightHide{
@includeslide-right-hide;
}
@mixinslide-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);
}
}
@keyframesslideBottom{
@includeslide-bottom;
}
@-webkit-keyframesslideBottom{
@includeslide-bottom;
}
@mixinslide-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);
}
}
@keyframesslideBottomHide{
@includeslide-bottom-hide;
}
@-webkit-keyframesslideBottomHide{
@includeslide-bottom-hide;
}
@mixinslide-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);
}
}
@keyframesslideLeft{
@includeslide-left;
}
@-webkit-keyframesslideLeft{
@includeslide-left;
}
@mixinslide-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);
}
}
@keyframesslideLeftHide{
@includeslide-left-hide;
}
@-webkit-keyframesslideLeftHide{
@includeslide-left-hide;
}
@mixinpopup-hide{
0%{
z-index:99999;
opacity:1;
}
100%{
z-index:-1;
opacity:0;
}
}
@keyframespopupHide{
@includepopup-hide;
}
@-webkit-keyframespopupHide{
@includepopup-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:slideTop0.6slinearforwards;
-moz-animation:slideTop0.6slinearforwards;
-ms-animation:slideTop0.6slinearforwards;
-o-animation:slideTop0.6slinearforwards;
animation:slideTop0.6slinearforwards;
}
}
&.right{
.popup-wrapper{
-webkit-animation:slideRight0.6slinearforwards;
-moz-animation:slideRight0.6slinearforwards;
-ms-animation:slideRight0.6slinearforwards;
-o-animation:slideRight0.6slinearforwards;
animation:slideRight0.6slinearforwards;
}
}
&.bottom{
.popup-wrapper{
-webkit-animation:slideBottom0.6slinearforwards;
-moz-animation:slideBottom0.6slinearforwards;
-ms-animation:slideBottom0.6slinearforwards;
-o-animation:slideBottom0.6slinearforwards;
animation:slideBottom0.6slinearforwards;
}
}
&.left{
.popup-wrapper{
-webkit-animation:slideLeft0.6slinearforwards;
-moz-animation:slideLeft0.6slinearforwards;
-ms-animation:slideLeft0.6slinearforwards;
-o-animation:slideLeft0.6slinearforwards;
animation:slideLeft0.6slinearforwards;
}
}
}
&.hide{
-webkit-animation:popupHide0.7slinearforwards;
-moz-animation:popupHide0.7slinearforwards;
-ms-animation:popupHide0.7slinearforwards;
-o-animation:popupHide0.7slinearforwards;
animation:popupHide0.7slinearforwards;
&.top{
.popup-wrapper{
-webkit-animation:slideTopHide0.6slinearforwards;
-moz-animation:slideTopHide0.6slinearforwards;
-ms-animation:slideTopHide0.6slinearforwards;
-o-animation:slideTopHide0.6slinearforwards;
animation:slideTopHide0.6slinearforwards;
}
}
&.right{
.popup-wrapper{
-webkit-animation:slideRightHide0.6slinearforwards;
-moz-animation:slideRightHide0.6slinearforwards;
-ms-animation:slideRightHide0.6slinearforwards;
-o-animation:slideRightHide0.6slinearforwards;
animation:slideRightHide0.6slinearforwards;
}
}
&.bottom{
.popup-wrapper{
-webkit-animation:slideBottomHide0.6slinearforwards;
-moz-animation:slideBottomHide0.6slinearforwards;
-ms-animation:slideBottomHide0.6slinearforwards;
-o-animation:slideBottomHide0.6slinearforwards;
animation:slideBottomHide0.6slinearforwards;
}
}
&.left{
.popup-wrapper{
-webkit-animation:slideLeftHide0.6slinearforwards;
-moz-animation:slideLeftHide0.6slinearforwards;
-ms-animation:slideLeftHide0.6slinearforwards;
-o-animation:slideLeftHide0.6slinearforwards;
animation:slideLeftHide0.6slinearforwards;
}
}
}
}
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代码:
classPopupComponent{
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";
}
/**
*给弹窗的标题和主体添加内容
*@paramObjectcontentObj传递的对象
*/
setContentForPopup(contentObj={'title':'title','body':'body'}){
try{
if(!TB.isObject(contentObj)){
thrownewError("TheparamofsetContentForPopupfunctionerror!");
}
letvalue;
for(letpropincontentObj){
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("Popupelementisnotexist!");
console.error(e);
}
}
/**
*删除弹窗的类名
*@returnvoid
*/
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;
}
/**
*弹窗隐藏
*@returnvoid
*/
popupHide(){
if(this.popupElClasslist.contains(this.SHOWCLASSNAME)){
this.popupElClasslist.remove(this.SHOWCLASSNAME);
this.popupElClasslist.add(this.HIDECLASSNAME);
}
}
/**
*弹窗显示
*@returnvoid
*/
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',
});
}
/**
*按钮容器的点击事件
*@paramObjecte点击的事件event
*@returnvoid
*/
btnGroupClickEvent(e){
letbtnEl=e.target||e.srcElement;
if(!TB.isElement(btnEl)){
thrownewError("Getbtnelementerror!");
}
this.position=btnEl.getAttribute("data-position");
if(!TB.isString(this.position)||(this.LEGVALS.indexOf(this.position)<0)){
thrownewError("Cannotgetpositionvaluefrombtnelement!");
}
this.popupShow();
}
/**
*给DOM元素添加点击事件
*@paramObjectelem添加点击事件的dom元素
*@paramFunctionfn触发事件调用的回调函数
*/
addClickEventFormElem(elem,fn){
TB.addHandler.call(this,elem,'click',fn,false);
}
/**
*初始化函数
*@returnvoid
*/
init(){
this.addClickEventFormElem(this.btnGroupEl,this.btnGroupClickEvent);
this.addClickEventFormElem(this.cancelBtnEl,this.popupHide);
this.addClickEventFormElem(this.confirmBtnEl,this.popupHide);
}
}
letpopupComponent=newPopupComponent();
popupComponent.init();
TB.addHandler:
/*
*给DOM元素添加事件
*@paramvoid
*@returncallbackfunction回调函数
**/
functionaddHandler(elem,type,callback,useCapture){
varcheckType=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);
}
}elseif(_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的指向
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。