javascript实现弹出层效果


Posted in Javascript onDecember 10, 2019

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

现在前端弹层使用的很频繁,如支付宝支付弹层等…所以掌握弹层是一个很重要的技能。如果只是简单的隐藏和切换,当然就不必说,我要说的html+animate+es6实现弹层;

javascript实现弹出层效果

javascript实现弹出层效果

javascript实现弹出层效果

javascript实现弹出层效果

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布局使得内容居中;它的直接子元素一般有两个,黑色背景层和内容容器;如图所示:

javascript实现弹出层效果

样式的动画相信前端的同学一般都知道怎么做;但是有一点要注意,不要试图使用display来实现动画;
我使用的解决的办法是首先

动画的显示隐藏使用的z-index和opacity;但是这样存在开始时,弹窗会缓缓隐藏,那么我们可以用一个类表示display: none;点击显示弹层时,移除该类即可;

对于js没什么好说的,无非是操作类名;但是有一点要注意事件注册和this的指向;
注意我的addHandler函数,该函数只会判断一次浏览器的环境,不需要反复的判断浏览器的环境;
在btnGroupClickEvent函数中this是指向PopupComponent类,而不是事件的event;所以addHandler函数中首先保存this的指向,然后使用call或者apply改变this的指向

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery 改变CSS样式基础代码
Feb 11 Javascript
从jQuery.camelCase()学习string.replace() 函数学习
Sep 13 Javascript
JavaScript 事件入门知识
Apr 13 Javascript
在JavaScript的AngularJS库中进行单元测试的方法
Jun 23 Javascript
JS表单验证的代码(常用)
Apr 08 Javascript
js 求时间差的实现代码
Apr 26 Javascript
分享JS数组求和与求最大值的方法
Aug 11 Javascript
原生JS实现图片轮播与淡入效果的简单实例
Aug 21 Javascript
详解React 在服务端渲染的实现
Nov 16 Javascript
Vue兼容ie9的问题全面解决方案
Jun 19 Javascript
使用 electron 实现类似新版 QQ 的登录界面效果(阴影、背景动画、窗体3D翻转)
Oct 23 Javascript
Node 代理访问的实现
Sep 19 Javascript
element表格翻页第2页从1开始编号(后端从0开始分页)
Dec 10 #Javascript
微信小程序实现注册登录功能(表单校验、错误提示)
Dec 10 #Javascript
微信小程序登陆注册功能的实现代码
Dec 10 #Javascript
vue excel上传预览和table内容下载到excel文件中
Dec 10 #Javascript
JS实现点餐自动选择框(案例分析)
Dec 10 #Javascript
原生js实现随机点餐效果
Dec 10 #Javascript
使用原生JS实现火锅点餐小程序(面向对象思想)
Dec 10 #Javascript
You might like
全国FM电台频率大全 - 31 新疆维吾尔族自治区
2020/03/11 无线电
检测png图片是否完整的php代码
2010/09/06 PHP
php中flush()、ob_flush()、ob_end_flush()的区别介绍
2013/02/17 PHP
php中array_unshift()修改数组key注意事项分析
2016/05/16 PHP
PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)
2016/09/11 PHP
老生常谈php 正则中的i,m,s,x,e分别表示什么
2017/03/02 PHP
thinkPHP微信分享接口JSSDK用法实例
2017/07/07 PHP
Javascript 学习书 推荐
2009/06/13 Javascript
初窥JQuery-Jquery简介 入门了解篇
2010/11/25 Javascript
javascript 按键事件(兼容各浏览器)
2013/12/20 Javascript
JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)
2016/08/11 Javascript
js手机号批量滚动抽奖实现代码
2020/04/17 Javascript
AngularJS实现页面跳转后自动弹出对话框实例代码
2017/08/02 Javascript
Angularjs上传文件组件flowjs功能
2017/08/07 Javascript
JavaScript(js)处理的HTML事件、键盘事件、鼠标事件简单示例
2019/11/19 Javascript
node.js使用http模块创建服务器和客户端完整示例
2020/02/10 Javascript
python按照多个字符对字符串进行分割的方法
2015/03/17 Python
Python正则表达式匹配HTML页面编码
2015/04/08 Python
Python中input与raw_input 之间的比较
2017/08/20 Python
Python实现将MySQL数据库表中的数据导出生成csv格式文件的方法
2018/01/11 Python
解决pycharm运行程序出现卡住scanning files to index索引的问题
2019/06/27 Python
如何使用python操作vmware
2019/07/27 Python
Python爬虫使用浏览器cookies:browsercookie过程解析
2019/10/22 Python
Django实现从数据库中获取到的数据转换为dict
2020/03/27 Python
python适合做数据挖掘吗
2020/06/16 Python
Python使用正则表达式实现爬虫数据抽取
2020/08/17 Python
python 如何调用 dubbo 接口
2020/09/24 Python
KIKO MILANO英国官网:意大利知名化妆品和护肤品品牌
2017/09/25 全球购物
荷兰牛仔裤网上商店:Jeans Centre
2018/04/03 全球购物
美国班级戒指、帽子和礼服、毕业产品、年鉴:Balfour
2018/11/01 全球购物
20年同学聚会邀请函
2014/02/04 职场文书
生物制药专业求职信
2014/03/11 职场文书
教师中国梦演讲稿
2014/04/23 职场文书
群众路线教育查摆剖析材料
2014/10/10 职场文书
销售经理助理岗位职责
2015/04/13 职场文书
2016全国“质量月”活动标语口号
2015/12/26 职场文书