HTML+CSS+JavaScript实现j可拖拽模态框

前言

模态框是指覆盖在父窗口上的子窗口,但在HTML网页中,并没有父窗口和子窗口的概念。这里是通过可隐藏的遮罩层和一个可隐藏的盒子来实现模态框的效果。

效果演示:

下面开始详细介绍如何实现一个可拖拽的模态框。只对 JS 部分详解,HTML 和 CSS 会放在文章底部的源代码中!

JavaScript详解

整体效果是由以下几个事件构成:

  • 点击立即登录按钮,弹出遮罩层和模态框。
  • 点击小叉号关闭模态框和遮罩层。
  • 鼠标在模态框的标题上按下时,计算鼠标在模态框中的坐标。
  • 给整个HTML文档添加鼠标移动事件,通过算法实现模态框跟随鼠标移动。
  • 鼠标在HTML文档中松开时,移除HTML文档的鼠标移动事件。

首先获取我们需要操作的元素

let but = document.querySelector('.but') // 立即登录按钮
let shade = document.querySelector('.shade')  // 遮罩层
let loginBox = document.querySelector('.login-box') // 模态框
let title = document.querySelector('.title')    // 模态框标题:用户登录
let exit = document.querySelector('.exit');  // 小叉号

点击立即登录按钮,弹出遮罩层和模态框。

but.addEventListener('click', function() {
    shade.style.display = "block";  // 显示遮罩层
    loginBox.style.display = "block";  // 显示模态框
});

点击小叉号关闭模态框和遮罩层。

exit.addEventListener('click', function() {
    shade.style.display = "none";  // 隐藏遮罩层
    loginBox.style.display = "none";  // 隐藏遮罩层
});

鼠标在模态框标题上按下时计算鼠标在模态框中的坐标:

title.addEventListener('mousedown', function(event) {
    let x = event.pageX - loginBox.offsetLeft;
    let y = event.pageY - loginBox.offsetTop;
});

event.pageX 和 event.pageY:获取鼠标在整个页面中的 x 坐标、y 坐标。

loginBox.offsetLeft 和 loginBox.offsetTop:获取模态框距离页面左边和上边的距离。

通过相减的方式计算出鼠标在模态框中的坐标。

鼠标在模态框标题上按下后,再给 document 对象添加鼠标移动事件:

title.addEventListener('mousedown', function(event) {
    let x = event.pageX - loginBox.offsetLeft;
    let y = event.pageY - loginBox.offsetTop;
    document.addEventListener('mousemove', function() {
        // 鼠标移动后的新坐标减去鼠标在模态框中的坐标,实现模态框跟随鼠标移动
        loginBox.style.left = (event.pageX - x)+"px";
        loginBox.style.top = (event.pageY - y)+"px";
    });
});

这里为什么不把鼠标移动事件给 title ?

如果把鼠标移动事件给 title 的话,鼠标移动过快,会脱离模态框,导致模态框无法跟随移动。

如果想看效果,把这里的 document 换成 title,然后快速拖动即可,这里不做演示!

到这里已经实现了模态框跟随鼠标移动,但当我们松开鼠标后,发现模态框依旧跟随鼠标移动。所以,还需要给 document 添加鼠标松开事件。

title.addEventListener('mousedown', function(event) {
    let x = event.pageX - loginBox.offsetLeft;
    let y = event.pageY - loginBox.offsetTop;
    document.addEventListener('mousemove', loginBoxMove);
    // 这里需要把鼠标移动事件函数写在外面,因为移除事件监听器时也会用到!
    function loginBoxMove(event) {
        loginBox.style.left = (event.pageX - x)+"px";
        loginBox.style.top = (event.pageY - y)+"px";
    }
    document.addEventListener('mouseup', function() {
        document.removeEventListener('mousemove', loginBoxMove);
    })
});

这里为什么不把鼠标松开事件给 title ?

还是会遇到上述类似的情况,大家可以自行尝试!

源代码

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>模态框</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            letter-spacing: 3px;
        }
        body {
            background-color: #ffbf84;
        }
        /* 立即登录按钮和模态框水平垂直居中 */
        .but, .login-box {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }
        /* 遮罩层 */
        .shade {
            display: none;
            position: absolute;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, .3);
            /* 这里一定要把遮罩层移到重叠元素的上层,就可以造成父窗口无法操作的效果 */
            z-index: 1;
        }
        /* 立即登录按钮 */
        .but {
            cursor: pointer;
            display: block;
            width: 200px;
            height: 60px;
            border-radius: 30px;
            box-shadow: 0 10px 10px rgba(10, 20, 20, .2);
            background-color: #fa8282;
            color: #fff;
            font-size: 25px;
            text-align: center;
            line-height: 60px;
        }
        .but:hover {
            transition: background-color 0.5s;
            background-color: #f36886;
        }
        /* 模态框 */
        .login-box {
            display: none;
            width: 350px;
            height: 250px;
            border: 1px solid rgb(216, 216, 216);
            border-radius: 10px;
            box-shadow: 5px 5px 10px rgba(10, 20, 20, .2), -5px -5px 10px rgba(10, 20, 20, .2);
            background-color: #fff;
            /* 和遮罩层同理,模态框一定要在最上层 */
            z-index: 1;
        }
        .login-box .title {
            cursor: move;
            user-select: none;  /* 禁止用户选中文字 */
            position: relative;
            width: 100%;
            height: 70px;
            color: #3f3f3f;
            font-size: 20px;
            font-weight: 700;
            text-align: center;
            line-height: 70px;
        }
        .login-box .title .exit {
            position: absolute;
            top: -10px;
            right: 10px;
            font-size: 30px;
        }
        .login-box .title .exit:hover {
            cursor: pointer;
            text-shadow: 2px 2px 4px rgba(10, 20, 20, .5);
        }
        .login-box form {
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            padding: 10px 0;
        }
        .login-box form .input-box {
            width: 60%;
            height: 35px;
            margin-bottom: 20px;
            padding: 0px 10px;
            border: 1px solid #3f3f3f;
            border-radius: 8px;
            color: #3f3f3f;
            font-size: 16px;
            font-weight: 700;
        }
        .login-box form .input-box:focus {
            outline: none;
        }
        .login-box form .login-but {
            width: 120px;
            height: 35px;
            border: none;
            background-color: #fa8282;
            border-radius: 8px;
            color: #fff;
            font-size: 20px;
            font-weight: 700;
        }
        .login-box form .login-but:hover {
            background-color: #f36886;
        }
    </style>
</head>
<body>
    <!-- 遮罩层 -->
    <div class="shade"></div>
    <!-- 登录按钮 -->
    <span class="but">立即登录</span>
    <!-- 模态框 -->
    <div class="login-box">
        <div class="title">
            用户登录
            <span class="exit">×</span>
        </div>
        <form action="">
            <input type="text" class="input-box" placeholder="用户名">
            <input type="password" class="input-box" placeholder="密码">
            <input type="submit" class="login-but" value="登录">
        </form>
    </div>
    <script>
        let but = document.querySelector('.but');
        let shade = document.querySelector('.shade');
        let loginBox = document.querySelector('.login-box');
        let title = document.querySelector('.title');
        let exit = document.querySelector('.exit');
 
        // 立即登录按钮点击事件
        but.addEventListener('click', function() {
            shade.style.display = "block";
            loginBox.style.display = "block";
        });
 
        // 关闭模态框事件
        exit.addEventListener('click', function() {
            shade.style.display = "none";
            loginBox.style.display = "none";
        });
 
        // 拖动标题区域可移动模态框
        title.addEventListener('mousedown', function(event) {
            // 计算鼠标在登录框中坐标
            let x = event.pageX - loginBox.offsetLeft;
            let y = event.pageY - loginBox.offsetTop;
            // 给页面添加鼠标移动事件
            document.addEventListener('mousemove', loginBoxMove);
            function loginBoxMove(event) {
                loginBox.style.left = (event.pageX - x)+"px";
                loginBox.style.top = (event.pageY - y)+"px";
            }
            // 鼠标松开后移除页面的鼠标移动事件
            document.addEventListener('mouseup', function() {
                document.removeEventListener('mousemove', loginBoxMove);
            })
        });
    </script>
</body>
</html>

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

(0)

相关推荐

  • js实现拖动模态框效果

    本文实例为大家分享了js实现拖动模态框效果的具体代码,供大家参考,具体内容如下 1.实现效果: 点击链接,弹出模态框.点击关闭,关闭模态框. 点击标题部分,可以随意移动模态框的位置. 主要是获取鼠标位置. 2.思路: 3.代码: <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta http-equiv="

  • JS实现拖动模态框案例

    本文实例为大家分享了JS实现拖动模态框的具体代码,供大家参考,具体内容如下 效果图: 需求分析: 点击登录后登录表单和遮罩层显示,点击关闭按钮隐藏. 输入密码时可以明文查看或者隐藏. 在表单的头部按下鼠标后可以拖拽表单. 鼠标弹起拖拽结束. 话不多说,我们直接上代码: <!DOCTYPE html> <html>   <head lang="en">     <meta charset="UTF-8">     <

  • js实现模态框的拖拽效果

    本文实例为大家分享了js实现模态框拖拽效果的具体代码,供大家参考,具体内容如下 之前学习js遇到了这样的需求:鼠标按下后,移动鼠标,模态框随鼠标移动,鼠标松开,模态框也不会随鼠标移动.<完整的代码在最后哦> 分析思路: 1.点击弹出层,模态框和遮挡层就会显示出来.display:block2.点击关闭按钮,模态框和遮挡层就会隐藏.display:none 3.在页面中拖拽的步骤:鼠标按下并移动,之后松开鼠标4.触发事件是鼠标按下mousedown,鼠标移动是mousemove,鼠标松开:mou

  • js实现拖动模态框

    模态框,我们也叫弹出框,可以在网易云,京东等之类的网页中看到. 效果如下: 代码思路: 1.点击弹出层,会弹出模态框,并且显示灰色半透明的遮挡层. 2.点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层. 3.鼠标放到模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动. 4.鼠标松开,可以停止拖动模态框移动. 5.在页面中拖拽的原理︰鼠标按下并且移动,之后松开鼠标 6.触发事件是鼠标按下mousedown,鼠标移动mousemove鼠标松开mouseup 7.拖拽过程:鼠标移动过程中,

  • JavaScript实现模态框拖拽效果

    在这里做一个模态框拖曳的案例,在这里要实现的功能有: 1.点击弹出层, 会弹出模态框, 并且显示灰色半透明的遮挡层. 2.点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层. 3.鼠标放到模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动. 4.鼠标松开,可以停止拖动模态框移动. 实现思路为: 点击弹出层, 模态框和遮挡层就会显示出来display:block; 点击关闭按钮,模态框和遮挡层就会隐藏起来 display:none; 在页面中拖拽的原理: 鼠标按下并且移动, 之后松开鼠标

  • JavaScript实现可拖动模态框

    本文实例为大家分享了JavaScript实现可拖动模态框的具体代码,供大家参考,具体内容如下 代码: HTML代码部分: <style> * { margin: 0px; padding: 0px; } .login-header { width: 100%; text-align: center; height: 30px; font-size: 24px; line-height: 30px; cursor: pointer; } .login { display: none; width

  • HTML+CSS+JavaScript实现j可拖拽模态框

    前言 模态框是指覆盖在父窗口上的子窗口,但在HTML网页中,并没有父窗口和子窗口的概念.这里是通过可隐藏的遮罩层和一个可隐藏的盒子来实现模态框的效果. 效果演示: 下面开始详细介绍如何实现一个可拖拽的模态框.只对 JS 部分详解,HTML 和 CSS 会放在文章底部的源代码中! JavaScript详解 整体效果是由以下几个事件构成: 点击立即登录按钮,弹出遮罩层和模态框. 点击小叉号关闭模态框和遮罩层. 鼠标在模态框的标题上按下时,计算鼠标在模态框中的坐标. 给整个HTML文档添加鼠标移动事件

  • react实现拖拽模态框

    前言 实际开发中,模态框展现数据会经常出现.但不幸的是有时功能开发完了,UI同学突然提出需求希望模态框能拖拽.本文使用的模态框由 ant design 3.0 的 Modal 组件封装而成,如何在不修改原来代码的基础上实现拖拽呢.最终效果图如下: 实践 1.创建高阶组件DragHoc 新建文件ModalDrag/index.js,将下面代码copy进去 DragObj是具体拖拽的原生js代码,后面再看 DragHoc是创建高阶组件的函数,其中参数InnerComponent是需要被改造的模态框组

  • JavaScript实现的简单拖拽效果

    本文实例讲述了JavaScript实现的简单拖拽效果.分享给大家供大家参考.具体实现方法如下: <!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">

  • JavaScript实现简单的拖拽效果

    本文实例为大家分享了JavaScript实现简单的拖拽效果的具体代码,供大家参考,具体内容如下 1.先搭架子: * { margin: 0; padding: 0; } p { background: skyblue; text-align: center; } html, body { width: 100%; height: 100%; } .mask { width: 100%; height: 100%; position: fixed; left: 0; top: 0; backgro

  • jQuery实现鼠标拖拽登录框移动效果

    本文实例为大家分享了jQuery鼠标拖拽登录框移动的具体代码,供大家参考,具体内容如下 1.jQuery代码 <script src="js/jquery-3.5.1.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $(function () { // 点击登录跳转 $(

  • 原生JS实现可拖拽登录框

    本文分享一个用原生JS实现的可拖拽登录框,效果如下: 实现的代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>原生JS实现可拖拽登录框</title> <style type="text/css"

  • Vue实现拖拽穿梭框功能四种方式实例详解

    目录 一.使用原生js实现拖拽 二.VUe使用js实现拖拽穿梭框 三.Vue 拖拽组件 vuedraggable 四.Awe-dnd指令封装 一.使用原生js实现拖拽 <html lang="en"> <head> <meta charset="UTF-8" /> <title>Lazyload</title> <style> .drag { background-color: skyblue;

  • javascript动画之模拟拖拽效果篇

    先看看实现效果图, 模拟拖拽最终效果和在桌面上移动文件夹的效果类似 原理介绍 鼠标按下时,拖拽开始.鼠标移动时,被拖拽元素跟着鼠标一起移动.鼠标抬起时,拖拽结束 所以,拖拽的重点是确定被拖拽元素是如何移动的 假设,鼠标按下时,鼠标对象的clientX和clientY分别为x1和x2.元素距离视口左上角x轴和y轴分别为x0和y0 鼠标移动的某一时刻,clientX和clientY分别为x2和y2 所以,元素移动的x轴和y轴距离分别为x2-x1和y2-y1 元素移动后,元素距离视口左上角x轴和y轴的

  • Javascript实现重力弹跳拖拽运动效果示例

    演示地址: http://www.ihuxu.com/project/gcdmove/ 调用示例: var GCDM = gcdMove(oDiv,100,0); GCDM.startMove();//开始运动 GCDM.stopMove();//结束运动 该段JS代码已经封装好了,代码如下: 简要说明 - obj为要改动的对象元素,通常为某个div:iSpeedX,iSpeedY为div出师的横向(右侧),竖向(下)的初始速度,当然也可以设为零. 复制代码 代码如下: /** * @Desc

  • javascript实现了照片拖拽点击置顶的照片墙代码

    演示图 styles.css *{ /*清空所有元素默认的外边距和内边距*/ } .photo_wall{ background:url(bg.jpg); /*定义照片墙的默认背景*/ background-size:cover; /*使照片墙的背景填充照片墙*/ width:1200px; /*设置照片墙的宽高*/ height:500px; margin:40px auto; /*设置照片墙的外边距*/ display:-webkit-box; /*使用CSS3的盒模型之流式布局*/ dis

随机推荐