美文网首页
弹窗封装(一)/咋样动态节点实现过渡动画

弹窗封装(一)/咋样动态节点实现过渡动画

作者: Raral | 来源:发表于2021-03-04 11:21 被阅读0次

在前端开发中,我们大量使用开源很多UI框架和js框架,让我们使用的越好,做项目越快,但是同时让我们也对最基本的css属性和js最基本和最底层的api都遗忘,所以我们通过自己封装插件和组件,让我们更容易拾起最基本的知识点;以下我会从3个部分总结这个过程:1.原生js和jquery实现基本弹框效果,2.使用面向对象js和jquery常用封装方法,3.通过vue封装和优化弹窗组件

  1. 通过js和jquery实现弹窗效果

静态节点实现(有弊端哟)

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>原生Popup弹出层</title>
   <style>
       * {
           margin: 0;
           padding: 0;
       }
       body {
          overflow: hidden;
       }
       .mask {
           width: 100%;
           height: 100vh;
           background-color: black;
           position: absolute;
           top: 0;
           left: 0;
           right: 0;
           bottom: 0;
           z-index: 1;
           opacity: 0;
           visibility: hidden;
           transition: all .3s linear;
       }
       .view {
           width: 100%;
           height: 0;
           background-color: #fff;
           position: absolute;
           left: 0;
           bottom: 0;
           z-index: 1000;
           display: block;
           transition: all .3s linear;
       }
       .show {
           opacity: .6;
           visibility: visible;
       }
       .show2 {
           height: 12.5rem;
       }
       
   </style>
</head>
<body>
   <!-- 不要使用 display 会影响过渡动画呦!!! -->
   <div>
       <button id="btn">test</button>
       <div>fsdfasd</div>
   </div>
   <div class="popup">
       <!-- 遮罩层 -->
       <div class="mask"></div>
       <!-- 显示层 -->
       <div class="view">
           显示东西
       </div>
   </div>
   
</body>
<script>
   //原生js版
   var popup = document.getElementsByClassName("popup")[0];
   var btn = document.getElementById("btn");
   var mask = document.getElementsByClassName("mask")[0];
   var view = document.querySelector(".view");
   btn.addEventListener('click', function() {
       mask.classList.add("show");
       view.classList.add("show2");
   }, false)

   popup.addEventListener('click', function(e) {
       console.log(e.currentTarget)//  事件绑定的元素
       console.log(e.target);//用户点击的真实元素
       mask.classList.remove("show");
       view.classList.remove("show2");
       // if(e.target.className == "")
   }, false)


   // jquery版
   $(function() {
       console.log($);
       $("#btn").click(() => {
           $(".mask").addClass("show");
           $(".view").addClass("show2");
       })
       $(".popup").click(() => {
           $(".mask").removeClass("show");
           $(".view").removeClass("show2");
       })
   })

</script>
</html>

bug:

  1. 该类名.popup元素一直存在与dom中。我们要达到效果,用户点击时,插入弹出层的节点,关闭时,销毁弹出层的节点,所以我们要动态的插入和销毁 .popup节点

js动态节点实现弹框(优化静态节点实现)

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>原生Popup弹出层</title>
   <style>
       * {
           margin: 0;
           padding: 0;
       }
        body {
          overflow: hidden;
       }
       .mask {
           width: 100%;
           height: 100vh;
           background-color: black;
           position: absolute;
           top: 0;
           left: 0;
           right: 0;
           bottom: 0;
           z-index: 1;
           opacity: 0;
           visibility: hidden;
           transition: all 1s linear;
       }
       .view {
           width: 100%;
           height: 0;
           background-color: #fff;
           position: absolute;
           left: 0;
           bottom: 0;
           z-index: 1000;
           display: block;
           transition: all 1s linear;
       }
       .show {
           opacity: .6;
           visibility: visible;
       }
       .show2 {
           height: 12.5rem;
       }

 
   </style>
</head>
<body>
   <!-- 不要使用 display 会影响过渡动画呦!!! -->
   <div>
       
       <button id="btn">test</button>
       <div class="page">fsdfasd</div>
   </div>
 
   
</body>
<script>
   window.onload = function() {
       // 获取操作的dom对象
       var oTest = document.getElementById("btn");
       var oMask = null;
       var oView = null;
       function createPopup() {
            //获取参数信息
           // var sHeight = document.documentElement.scrollHeight;
           // var sWidth = document.documentElement.scrollWidth;
           // 我们这里可以使用 字符串转node节点对象,来创建弹出层的dom结构,方便简洁
           var strHtml = `
               <div class="popup">
                   <div class="mask"></div>
                   <div class="view">
                       显示内容
                   </div>
               </div>
           `
           //生成节点
           var popupDom = new DOMParser().parseFromString(strHtml,'text/html').body.childNodes[0];
           document.body.appendChild(popupDom);
       }
       
       function destoryPopup() {
           var popupNode = document.body.querySelectorAll(".popup");
           if(popupNode.length <= 0) return;
           Array.prototype.forEach.call(popupNode, (node) => {
               document.body.removeChild(node);
           })
       }

       oTest.addEventListener('click', function() {
           createPopup();
           // 注意: 添加过渡动画时,要放入宏观任务队列
           setTimeout(() => {
                //添加过渡类名
               oMask = document.documentElement.querySelector(".mask");
               oView = document.documentElement.querySelector(".view");
               oMask.classList.add("show");
               oView.classList.add("show2");
           })
          
       }, false)
       document.body.addEventListener('click', function(e) {
           if(e.target.classList.contains("mask")) {
               oMask.classList.remove("show");
               oView.classList.remove("show2");
               setTimeout(() => {
                   destoryPopup();
               }, 1000);// 这个时间和你过渡动画时间一致
           }
       }, false)
   }
   
   /* 1. 咋样给动态的dom节点添加过渡动画呢?
       为什么没有动画?
           在js单线程执行,尤其在同步任务中,所有的执行逻辑都是同步进行,也就是说 创建遮罩层和添加show类名是同时的,所以导致没有效果
           我们要把添加过渡最后类名,添加到异步队列中执行。setTimeout()
   */
</script>
</html>

注意:
动态的dom节点添加过渡动画呢一定要注意js单线程执行同步任务,但是我们的过渡动画是有时间段的,也就是两种状态的。在js单线程执行,尤其在同步任务中,所有的执行逻辑都是同步进行,也就是说 创建遮罩层和添加show类名是同时的,所以导致m没有效果我们要把添加过渡最后类名,添加到异步队列中执行。setTimeout()实现宏观任务队列

promise异步队列

jquery动态节点实现弹框

$(function() {
    
    function createPopup() {
        var template = `
                <div class="popup">
                    <div class="mask"></div>
                    <div class="view">
                        显示内容
                    </div>
                </div>
        ` 
        //jquery append方法加强了可以传入字符串;原生js只能传node对象
        $("body").append(template);
    }
 
    function destoryPopup() {
        if($(".popup").length <= 0) return;
        $(".popup").remove();
    }
    // destoryPopup()
    
    $("#btn").click(() => {
        createPopup();
        setTimeout(() => {
            $(".mask").addClass("show");
            $(".view").addClass("show2");
        });
    })

    $("body").on("click",(e) => {
        if(e.target.classList.contains("mask")) {
                $(".mask").removeClass("show");
                $(".view").removeClass("show2");
                setTimeout(() => {
                    destoryPopup();
                }, 1000);// 这个时间和你过渡动画时间一致
            }
    })
})

我们对原生js和jquery实现思路已经掌握,接下来我们要常用封装手段实现,封装
可以提前参考面向对象oop封装

相关文章

网友评论

      本文标题:弹窗封装(一)/咋样动态节点实现过渡动画

      本文链接:https://www.haomeiwen.com/subject/cvahqltx.html