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

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

作者: 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