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的指向

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

(0)

相关推荐

  • js弹出层之1:JQuery.Boxy (二)

    4.1.手动创建实例 复制代码 代码如下: <script type="text/javascript"> $(function() { $("#a1").click(function() { //实例化一个Boxy对象 var box1 = new Boxy("<h3>这个参数是显示的内容</h3>" //显示内容 , { title: "标题", //对话框标题 modal: false

  • js写一个弹出层并锁屏效果实现代码

    复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv=&qu

  • Js制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法

    这两天要用到正好练练手,比想象中碰到的问题要多,比如: ie6背景透明 ie6居中显示 还有对js对象的理解 openID=显示按钮,conID=需要显示的div,closeID=关闭按钮 解决了: 1.可以遮挡ie6下的select元素 但是在ie6下div没有透明度 2.弹出的div可以一直在浏览器屏幕中间显示 问题: 1.目前不支持.class 只支持#id 2.需要显示的div需要自己设置css 3.在ie6下需要设置css 例如div {_position: absolute;_top

  • js+css 实现遮罩居中弹出层(随浏览器窗口滚动条滚动)

    js+css 实现遮罩居中弹出层(随浏览器窗口滚动条滚动) 复制代码 代码如下: <!doctype html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> *{}{margin:0;padding:0;} html{}{_background:url(about:blank);} /**//*

  • 使用js实现关闭js弹出层的窗口

    <script type="text/javascript">function toggle() {  theObj = document.getElementById('Sunyanzi').style;  if (  theObj.display == "none" ) theObj.display = "block"; else theObj.display = "none";}</script>

  • js 点击页面其他地方关闭弹出层(示例代码)

    复制代码 代码如下: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <style type="text/css"> <!-- *{font-size:12px;font-family:Verdana, Gen

  • js实现div弹出层的方法

    本文实例讲述了js实现div弹出层的方法.分享给大家供大家参考.具体分析如下: 话说现在各种插件出来了要实现弹出层真是太简单了,但个人有时觉得那些插件不实用经常会找一些纯js原生态的东西,下面来给各位分享一个原生太js div弹出层实例,有需要的朋友可一起看看. 这个不用多说了,直接贴代码吧.有码有注释: 复制代码 代码如下: /*  * 弹出DIV层 */ function showDiv() { var Idiv     = document.getElementById("Idiv&quo

  • js与css实现弹出层覆盖整个页面的方法

    本文实例讲述了js与css实现弹出层覆盖整个页面的方法.分享给大家供大家参考.具体实现方法如下: 弹出层透明背景加框的常用样式和结构如下: 复制代码 代码如下: .alertMessageBg{ position:fixed; _position:absolute; width:100%; height:100%; left:0; top:0; background:#000; opacity:0.5; -moz-opacity:0.5; filter:alpha(opacity=50); z-

  • Js Jquery创建一个弹出层可加载一个页面

    复制代码 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"

  • jquery.artwl.thickbox.js 一个非常简单好用的jQuery弹出层插件

    最终效果: 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>弹出层插件:jquery.artwl.thickbox.js</title> <script src="/js_lib/jQuery-1

随机推荐