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

article/2025/8/19 0:55:15

前言

模态框是指覆盖在父窗口上的子窗口,但在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>


http://chatgpt.dhexx.cn/article/7ghCYUDg.shtml

相关文章

Bootstrap系列之模态框(Modal)

文章の目录 1、工作原理2、示例2.1、Modal组件2.2、在线演示2.3、静态背景2.4、滚动内容2.5、垂直居中2.6、提示和弹窗2.7、使用网格2.8、不同模态框的内容2.9、改变动画2.10、移除动画2.11、动态高度2.12、Accessibility2.13、嵌入YouTube视频 3、Optional sizes4、用法4.1、通…

Oracle数据迁移

本文主要提及使用exp,imp以及Oracle数据泵等工具如何进行数据迁移&#xff1a; 一、数据迁移工具 1、数据迁移工具 &#xff08;1&#xff09;数据泵 &#xff08;2&#xff09;外部表&#xff1a;external table &#xff08;3&#xff09;数据加载工具&#xff1a;sqllo…

MySQL数据库- 几种数据迁移的方法详解都在这了!看完必懂

数据迁移的几种方式 - MySQL数据库 本文关键字&#xff1a;MySQL、数据库、数据迁移、导入、导出 文章目录 数据迁移的几种方式 - MySQL数据库 一、数据迁移 1. 数据的生命周期2. 数据迁移的发生二、数据导出 1. 命令方式2. 软件方式三、数据导入 1. 命令方式2. 软件方式四、…

数据迁移方法

在我的《高并发系统设计目标之可扩展性》博文中提到&#xff0c;随着业务的发展&#xff0c;我们会沿着AKF的Y轴进行微服务化的改造。但是沿着Y轴的重构过程中往往涉及到分库分表。那么这时就需要进行数据库的迁移了。沿着AKF的Z轴也类似&#xff0c;那么迁移有什么原则呢&…

如何高效地进行大规模数据迁移?

导读 我们在做一次系统业务模型重构的时候&#xff0c;往往会遇到把旧模型表中的数据迁移到新模型表中&#xff0c;如果这时候&#xff0c;我们旧表中的数据规模已达到千万级以上&#xff0c;那么&#xff0c;这个从旧表迁移到新表的过程会非常漫长&#xff0c;而业务仍需快速推…

电脑数据怎么迁移?

“最近我的电脑越来越卡&#xff0c;运行程序时还会出现卡死奔溃的现象&#xff0c;陪伴我多年的电脑到了退休的时候了。购买了一台新款的笔记本电脑&#xff0c;打开软件运行多么的流畅&#xff0c;别提多高兴了&#xff01;可是&#xff0c;我想把旧电脑的数据导入到新电脑怎…

数据库整体迁移

1.迁移方法概述: 使用Navicat Premium 分别与源数据库和目标数据库建立连接,然后借助Navicat Premium自带的数据传输功能,实现Oracle数据库的迁移.其实跟从MySQL数据库迁移到oracle数据库是一个套路. O(∩_∩)O~ 听起来,是不是很简单,其实就是很简单!下边我就讲一下具体实现的细…

数据库迁移的方法

数据库迁移的方法 我们今天以mysql为例&#xff0c;讲讲数据库迁移的四种方法。 1、将数据库倒出为sql文件&#xff0c;再重新导入&#xff08;推荐&#xff09;。 首先将mysql数据库锁定&#xff0c;并将内存中的数据写入磁盘。 flush tables with read lock ; 用mysqldump将t…

数据迁移——技术选型

日常我们在开发中&#xff0c;随着业务需求的变更&#xff0c;重构系统是很常见的事情。重构系统常见的一个场景是变更底层数据模型与存储结构。这种情况下就要对数据进行迁移&#xff0c;从而使业务能正常运行。 背景如下&#xff1a;老系统中使用了mongo数据库&#xff0c;由…

Oracle数据迁移MySQL

前言: 现今&#xff0c;Oracle数据迁移MySQL的需求已经越来越普遍&#xff0c;主要的迁移场景大致可以分为三类&#xff0c;第一类是涉及小表以及少量表的一次性迁移&#xff0c;无需进行增量同步&#xff0c;第二类是涉及大表以及多表的一次性迁移&#xff0c;第三类是涉及增…

电脑之间如何迁移数据?数据迁移方法描述

电脑之间如何迁移数据&#xff1f;当更换电脑时&#xff0c;很多人需要做的第一件事&#xff0c;就是将旧电脑的数据通过外置存储设备等拷贝到新电脑上&#xff0c;并且还要在新电脑上重新安装应用程序&#xff0c;步骤繁琐&#xff0c;耗费了大量的时间和精力不说&#xff0c;…

DB数据迁移方案

互联网系统&#xff0c;经常会有数据迁移的需求。系统从机房迁移到云平台&#xff0c;从一个云平台迁移到另一个云平台&#xff0c;系统重构后表结构发生了变化&#xff0c;分库分表&#xff0c;更换数据库选型等等&#xff0c;很多场景都需要迁移数据。 在互联网行业&#xf…

【OceanBase】四种不同的数据迁移方式

前言 OceanBase 已连续 9 年稳定支撑双 11&#xff0c;创新推出“三地五中心”城市级容灾新标准&#xff0c;在被誉为“数据库世界杯”的 TPC-C 和 TPC-H 测试上都刷新了世界纪录。自研一体化架构&#xff0c;兼顾分布式架构的扩展性与集中式架构的性能优势&#xff0c;用一套…

数据迁移介绍

数据迁移方案 数据迁移框架有几个比较有名应用比较广泛的开源项目&#xff1a;阿里datax&#xff0c;apache sqoop以及Pentaho kettle。这三个框架整体上工作原理类似&#xff0c;下面介绍阿里datax数据迁移框架。 对旧系统进行了重构&#xff0c;就需要把原来的数据迁移到新数…

代码技巧——数据迁移方案【建议收藏】

开发工作中&#xff0c;可能会遇到如"大表拆分"、"跨库数据迁移"等场景&#xff0c;本文介绍互联网常见架构下的数据迁移方案及实现&#xff1b; 1. 数据迁移的业务场景 以下是需要数据迁移的场景业务场景&#xff1b; 1.1 大表拆分 由于历史原因&…

【Pytorch】Label Smoothing

理论介绍可以参考 【Inception-v3】《Rethinking the Inception Architecture for Computer Vision》 中的 4.5 Model Regularization via Label Smoothing 本质就是用右边&#xff08;意会下就行&#xff09;的标签替换左边的 one-hot 编码形式&#xff0c;让网络别那么愤青&…

关于label smoothing(标签平滑)

目的&#xff1a; label smoothing常用于分类任务&#xff0c;防止模型在训练中过拟合&#xff0c;提高模型的泛化能力。 意义&#xff1a; 对于分类问题&#xff0c;我们通常使用one-hot编码&#xff0c;“非黑即白”&#xff0c;标签向量的目标类别概率为1&#xff0c;非目标…

【AI面试】hard label与soft label,Label Smoothing Loss 和 Smooth L1 Loss

往期文章: AI/CV面试,直达目录汇总【AI面试】NMS 与 Soft NMS 的辨析【AI面试】L1 loss、L2 loss和Smooth L1 Loss,L1正则化和L2正则化在一次询问chatGPT时候,在他的回答中,由smooth L1联想提到了Label Smoothing Loss 。我把问题贴到下面,和chatGPT的回答,供你参考。不…

标签平滑(label smoothing)

目录 1.标签平滑主要解决什么问题&#xff1f; 2.标签平滑是怎么操作的&#xff1f; 3.标签平滑公式 4.代码实现 标签平滑&#xff08;label smoothing&#xff09;出自GoogleNet v3 关于one-hot编码的详细知识请见&#xff1a;One-hot编码 1.标签平滑主要解决什么问题&…

指数平滑法 Exponential Smoothing

指数平滑法 Exponential Smoothing 指数平滑法&#xff0c;用于中短期经济发展趋势预测。 1 时间序列分析基础知识 1.1 时间序列分析前提假设 时间序列分析一般假设我们获得的数据在时域上具有一定的相互依赖关系&#xff0c;例如股票价格在t时刻很高&#xff0c;那么在t1时…