Web开发:一个可拖拽的模态框(HTML、CSS、JavaScript)

07-13 1614阅读

目录

一、需求描述

二、实现效果

三、完整代码

四、实现过程

1、HTML 页面结构

2、CSS 元素样式

3、JavaScript动态控制

(1)获取元素

(2)显示\隐藏遮罩层与模态框

(3)实现模态框拖动效果


一、需求描述

实现一个可以拖拽的模态框;

  • 点击打开按钮,显示模态框和遮罩层;
  • 点击关闭按钮或遮罩层,隐藏模态框和遮罩层;
  • 在模态框的标题栏按下并移动鼠标,模态框跟随鼠标移动(拖拽效果);

    二、实现效果

    1、点击按钮显示遮罩层和模态框

    Web开发:一个可拖拽的模态框(HTML、CSS、JavaScript)

    Web开发:一个可拖拽的模态框(HTML、CSS、JavaScript)

    2、在模态框标题栏按下并移动鼠标,模态框跟随移动

    Web开发:一个可拖拽的模态框(HTML、CSS、JavaScript)

    3、点击关闭按钮或者遮罩层隐藏模态框

    Web开发:一个可拖拽的模态框(HTML、CSS、JavaScript)

    三、完整代码

    【test.html】

    
    
        
        
        可拖拽的模态框
        
            * {
                margin: 0;
                padding: 0;
                caret-color: transparent;
            }
            .open-btn {
                display: inline-block;
                margin: 60px;
                padding: 10px 20px;
                font-size: 16px;
                color: #fff;
                background-color: #409eff;
                border: none;
                border-radius: 8px;
            }
            .modal-box {
                display: none;
                position: fixed;
                top: 120px;
                left: 60px;
                width: 400px;
                min-height: 200px;
                padding: 10px;
                background: #fff;
                border-radius: 8px;
                box-shadow: 0 0 4px 1px #acacac;
                z-index: 99999;
            }
            .modal-title {
                text-align: center;
                font-size: 18px;
                font-weight: 700;
                padding: 20px;
                border-bottom: 1px solid #ddd;
                cursor: move;
            }
            .modal-body {
                margin: 20px 0;
            }
            .close-btn {
                position: absolute;
                top: 6px;
                right: 6px;
                width: 18px;
                height: 18px;
                background-image: url("D:\\test\\close.svg");
                background-size: cover;
            }
            .mask {
                display: none;
                width: 100vw;
                height: 100vh;
                position: fixed;
                top: 0px;
                left: 0px;
                background: rgba(0, 0, 0, .3);
            }
        
    
    
        打开模态框
        
        
            一个可以拖拽的模态框
            内容区域不能拖到
            
        
    
    
        // 获取打开按钮
        var openBtn = document.querySelector(".open-btn");
        // 获取模态框
        var modalBox = document.querySelector(".modal-box");
        // 获取模态框标题
        var modalTitle = document.querySelector(".modal-title")
        // 获取关闭按钮
        var closeBtn = document.querySelector(".close-btn");
        // 获取遮罩层
        var maskBox = document.querySelector(".mask");
        // 2、显示\隐藏遮罩层与模态框
        // 2.1、点击打开按钮,显示模态框和遮罩层
        openBtn.addEventListener('click', function () {
            maskBox.style.display = "block";
            modalBox.style.display = "block";
        })
        // 2.2、点击关闭按钮 或者遮罩层 隐藏模态框和遮罩层
        closeBtn.addEventListener('click', function () {
            maskBox.style.display = "none";
            modalBox.style.display = "none";
        })
        maskBox.addEventListener('click', function () {
            maskBox.style.display = "none";
            modalBox.style.display = "none";
        })
        // 3、拖动模态框
        // 3.1 鼠标按下
        modalTitle.addEventListener('mousedown', function (e) {
            // 获取鼠标起始位置坐标
            var mouseX = e.pageX;
            var mouseY = e.pageY;
            // 模态框的初始左边距 上边距
            var modalBoxX = modalBox.offsetLeft;
            var modalBoxY = modalBox.offsetTop;
            // 3.2 鼠标移动 计算模态框的移动距离
            modalTitle.addEventListener('mousemove', moveMouse);
            // 3.3 鼠标弹起 移除鼠标移动事件
            modalTitle.addEventListener('mouseup', function () {
                modalTitle.removeEventListener('mousemove', moveMouse)
            })
            // 鼠标移动事件回调
            function moveMouse(e) {
                // 模态框移动的边距 = 模态框的起始边距 + 鼠标的相对移动值;
                modalBox.style.left = modalBoxX + (e.pageX - mouseX) + 'px';
                modalBox.style.top = modalBoxY + (e.pageY - mouseY) + 'px';
            }
        })
    
    

    四、实现过程

    1、HTML 页面结构

    • 一个按钮【button元素】,用来点击显示模态框和遮罩层;
    • 一个遮罩层【div元素】;
    • 一个模态框【div元素】,其中包含模态框的标题【div元素】、内容【div元素】和关闭按钮【div元素】;
          打开模态框
          
          
              一个可以拖拽的模态框
              内容区域不能拖到
              
          
      

      2、CSS 元素样式

      (1)按钮样式

      根据自己的喜好自行添加按钮的样式即可;

      .open-btn {
          display: inline-block;
          margin: 60px;
          padding: 10px 20px;
          font-size: 16px;
          color: #fff;
          background-color: #409eff;
          border: none;
          border-radius: 8px;
      }

      Web开发:一个可拖拽的模态框(HTML、CSS、JavaScript)

      (2)遮罩层样式 

      • 先不用设置遮罩层的display为none,先让它显示出来,便于观察;
      • 设置遮罩层的宽高分别为 100vw 和 100vh ,占满浏览器的整个窗口(根据浏览器窗口大小自适应,始终占满);
      • 遮罩层使用固定定位【 position: fixed; 】,使其不受其他元素的位置影响;
        .mask {
            /* display: none; */
            position: fixed;
            top: 0px;
            left: 0px;
            width: 100vw;
            height: 100vh;
            background: rgba(0, 0, 0, .3);
        }

         Web开发:一个可拖拽的模态框(HTML、CSS、JavaScript)

        (3)模态框样式

        • 模态框跟遮罩层一样,不用设置display为none;
        • 模态框也使用固定定位【 position: fixed; 】,使其不受其他元素的位置影响;
        • 模态框的标题设置cursor属性为move,当鼠标移动到模态框的标题位置时,会显示移动样式;
        • 模态框的关闭按钮,使用的是div元素,将其定位到模态框的右上角,并设置其背景为svg图标;
          .modal-box {
              /* display: none; */
              position: fixed;
              top: 120px;
              left: 60px;
              width: 400px;
              min-height: 200px;
              padding: 10px;
              background: #fff;
              border-radius: 8px;
              box-shadow: 0 0 4px 1px #acacac;
              z-index: 99999;
          }
          .modal-title {
              text-align: center;
              font-size: 18px;
              font-weight: 700;
              padding: 20px;
              border-bottom: 1px solid #ddd;
              cursor: move;
          }
          .modal-body {
              margin: 20px 0;
          }
          .close-btn {
              position: absolute;
              top: 6px;
              right: 6px;
              width: 18px;
              height: 18px;
              background-image: url("D:\\test\\close.svg");
              background-size: cover;
          }

          Web开发:一个可拖拽的模态框(HTML、CSS、JavaScript)

          3、JavaScript动态控制

          (1)获取元素

          将页面中需要操作的元素都进行获取;

          这里使用的是querySelector()方法来获取元素,是JavaScript中获取dom元素的方式之一;

              // 1、获取页面元素
              // 获取打开按钮
              var openBtn = document.querySelector(".open-btn");
              // 获取模态框
              var modalBox = document.querySelector(".modal-box");
              // 获取模态框标题
              var modalTitle = document.querySelector(".modal-title")
              // 获取关闭按钮
              var closeBtn = document.querySelector(".close-btn");
              // 获取遮罩层
              var maskBox = document.querySelector(".mask");
              ......
          

          (2)显示\隐藏遮罩层与模态框

          在控制遮罩层和模态框的显示与隐藏之前,需要先将其display属性设为none;

          .mask {
              display: none;
              ......
          }
          .modal-box {
              display: none;
              ......
          }

          根据案例需求,可以知道:

          • 遮罩层和模态框的显示与隐藏是同时的,模态框显示则遮罩层显示,模态框隐藏则遮罩层隐藏;
          • 当点击【打开模态框】按钮时,进行显示,所以需要给这个按钮注册点击事件,完成相应功能;
          • 当点击模态框中的【关闭按钮】或者遮罩层时,进行隐藏,所以需要给关闭按钮和遮罩层都注册鼠标点击事件,完成相应功能;
                ......
                // 2、显示\隐藏遮罩层与模态框
                // 2.1、点击打开按钮,显示模态框和遮罩层
                openBtn.addEventListener('click', function () {
                    maskBox.style.display = "block";
                    modalBox.style.display = "block";
                })
                // 2.2、点击关闭按钮 或者遮罩层 隐藏模态框和遮罩层
                closeBtn.addEventListener('click', function () {
                    maskBox.style.display = "none";
                    modalBox.style.display = "none";
                })
                maskBox.addEventListener('click', function () {
                    maskBox.style.display = "none";
                    modalBox.style.display = "none";
                })
                ......
            

            (3)实现模态框拖动效果

            根据案例需求,分析可知:

            • 模态框采用的是固定定位【 position: fixed;】,改变其 top 和 left 值就相当于是在移动了;
            • 模态框的移动距离实际就是鼠标的移动距离,加上模态框的起始位置坐标;
            • 鼠标的移动距离实际就是鼠标按下的位置,与鼠标移动时位置的差值;

              注册 mousedown 事件,鼠标按下,得到鼠标在模态框内的坐标,即起始位置;

              注册 mousemove 事件,鼠标移动,获得最新的鼠标位置,计算移动距离;

              注册 mouseup 事件,鼠标弹起,停止拖拽,解除鼠标移动事件;

              注意:

              • mousedown 、mousemove 、mouseup 触发的事件源是模态框的标题栏;
              • mousemove、mouseup 是在鼠标按下事件的基础上( 要写到mousedown 事件里面 );
                    ......
                    // 3、拖动模态框
                    // 3.1 鼠标按下
                    modalTitle.addEventListener('mousedown', function (e) {
                        // 获取鼠标起始位置坐标
                        var mouseX = e.pageX;
                        var mouseY = e.pageY;
                        // 模态框的初始左边距 上边距
                        var modalBoxX = modalBox.offsetLeft;
                        var modalBoxY = modalBox.offsetTop;
                        // 3.2 鼠标移动 计算模态框的移动距离
                        modalTitle.addEventListener('mousemove', moveMouse);
                        // 3.3 鼠标弹起 移除鼠标移动事件
                        modalTitle.addEventListener('mouseup', function() {
                            modalTitle.removeEventListener('mousemove', moveMouse)
                        })
                        // 鼠标移动事件回调
                        function moveMouse(e) {
                            // 模态框移动的边距 = 模态框的起始边距 + 鼠标的相对移动值;
                            modalBox.style.left = modalBoxX + (e.pageX - mouseX) + 'px';
                            modalBox.style.top = modalBoxY + (e.pageY - mouseY) + 'px';
                        }
                    })
                

                =========================================================================

                每天进步一点点~!

                记录下前端这个一个小知识~~! 

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]