当前位置: 首页 > news >正文

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

目录

一、需求描述

二、实现效果

三、完整代码

四、实现过程

1、HTML 页面结构

2、CSS 元素样式

3、JavaScript动态控制

(1)获取元素

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

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


一、需求描述

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

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

二、实现效果

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

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

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

三、完整代码

【test.html】

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>可拖拽的模态框</title><style>* {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);}</style>
</head><body><button class="open-btn">打开模态框</button><div class="mask"></div><div class="modal-box"><div class="modal-title">一个可以拖拽的模态框</div><div class="modal-body">内容区域不能拖到</div><div class="close-btn" /></div>
</body>
<script>// 获取打开按钮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';}})
</script></html>

四、实现过程

1、HTML 页面结构

  • 一个按钮【button元素】,用来点击显示模态框和遮罩层;
  • 一个遮罩层【div元素】;
  • 一个模态框【div元素】,其中包含模态框的标题【div元素】、内容【div元素】和关闭按钮【div元素】;
<body><button class="open-btn">打开模态框</button><div class="mask"></div><div class="modal-box"><div class="modal-title">一个可以拖拽的模态框</div><div class="modal-body">内容区域不能拖到</div><div class="close-btn" /></div>
</body>

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;
}

(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);
}

 

(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;
}

3、JavaScript动态控制

(1)获取元素

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

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

<script>// 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");......
</script>

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

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

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

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

  • 遮罩层和模态框的显示与隐藏是同时的,模态框显示则遮罩层显示,模态框隐藏则遮罩层隐藏;
  • 当点击【打开模态框】按钮时,进行显示,所以需要给这个按钮注册点击事件,完成相应功能;
  • 当点击模态框中的【关闭按钮】或者遮罩层时,进行隐藏,所以需要给关闭按钮和遮罩层都注册鼠标点击事件,完成相应功能;
<script>......// 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";})......
</script>

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

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

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

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

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

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

注意:

  • mousedown 、mousemove 、mouseup 触发的事件源是模态框的标题栏;
  • mousemove、mouseup 是在鼠标按下事件的基础上( 要写到mousedown 事件里面 );
<script>......// 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';}})
</script>

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

每天进步一点点~!

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

相关文章:

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

目录 一、需求描述 二、实现效果 三、完整代码 四、实现过程 1、HTML 页面结构 2、CSS 元素样式 3、JavaScript动态控制 &#xff08;1&#xff09;获取元素 &#xff08;2&#xff09;显示\隐藏遮罩层与模态框 &#xff08;3&#xff09;实现模态框拖动效果 一、需求…...

【深度学习】fooocusapi,docker,inpainting图像

基础镜像制作来源 fooocusapi接口官方写的&#xff1a; docker run -d --gpusall \-e NVIDIA_DRIVER_CAPABILITIEScompute,utility \-e NVIDIA_VISIBLE_DEVICESall \-p 8888:8888 konieshadow/fooocus-api会下载一些模型&#xff0c;下载完后推这个镜像 docker commit 4dfd1…...

算法017:二分查找

二分查找. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/binary-search/ 二分查找&#xff0c;其实是双指针的一种特殊情况&#xff0c;但是时间复杂度极低&#…...

谷粒商城实战笔记-37-前端基础-Vue-基本语法插件安装

文章目录 一&#xff0c;v-model1&#xff0c;双向绑定2&#xff0c;vue的双向绑定2.1 html元素上使用指令v-model2.2 model中声明对应属性2.3&#xff0c;验证view绑定modelmodel绑定view 完整代码 二&#xff0c;v-on1&#xff0c;指令简介2&#xff0c;在button按钮中添加v-…...

mybatis中的缓存(一级缓存、二级缓存)

文章目录 前言一、MyBatis 缓存概述二、一级缓存1_初识一级缓存2_一级缓存命中原则1_StatementId相同2_查询参数相同3_分页参数相同4_sql 语句5_环境 3_一级缓存的生命周期1_缓存的产生2_缓存的销毁3_网传的一些谣言 4_一级缓存核心源码5_总结 三、二级缓存1_开启二级缓存2_二级…...

实现自动化采购:食堂采购系统源码开发详解

本篇文章&#xff0c;笔者将详细介绍食堂采购系统的开发过程&#xff0c;从需求分析、系统设计到实现和测试&#xff0c;为您全面解析如何构建一个高效的自动化采购系统。 一、需求分析 1.采购计划管理 2.供应商管理 3.订单管理 4.库存管理 5.财务管理 6.数据分析与报告 …...

linux、windows、macos清空本地DNS缓存

文章目录 Linux&#xff1a;Windows&#xff1a;macOS&#xff1a; Linux&#xff1a; 对于使用systemd的操作系统&#xff08;如CentOS 7、Ubuntu 16.04&#xff09;&#xff0c;可以使用以下命令重启systemd-resolved服务来清除缓存&#xff1a; sudo systemctl restart sys…...

领夹麦克风哪个品牌好,电脑麦克风哪个品牌好,热门麦克风推荐

​在信息快速传播的时代&#xff0c;直播和视频创作成为了表达与交流的重要方式。对于追求卓越声音品质的创作者而言&#xff0c;一款性能卓越的无线麦克风宛如一把利剑。接下来&#xff0c;我要为大家介绍几款备受好评的无线麦克风&#xff0c;这些都是我在实际使用中体验良好…...

【第5章】Spring Cloud之Nacos服务注册和服务发现

文章目录 前言一、提供者1. 引入依赖2.配置 Nacos Server 地址3. 开启服务注册 二、消费者1. 引入依赖2.配置 Nacos Server 地址3. 开启服务注册 三、服务列表四、服务发现1. 获取服务列表2. 测试2.1 获取所有服务2.2 根据服务名获取服务信息 五、更多配置项总结 前言 本节通过…...

Springboot 启动时Bean的创建与注入(一)-面试热点-springboot源码解读-xunznux

Springboot 启动时Bean的创建与注入&#xff0c;以及对应的源码解读 文章目录 Springboot 启动时Bean的创建与注入&#xff0c;以及对应的源码解读构建Web项目流程图&#xff1a;堆栈信息&#xff1a;堆栈信息简介堆栈信息源码详解1、main:10, DemoApplication (com.xun.demo)2…...

单调栈(随缘复习到了,顺手刷了)

也是不知道为什么突然又复习到单调栈了&#xff0c;所以顺手刷了三道题&#xff0c;总结一下 P6503 [COCI2010-2011#3] DIFERENCIJA 思路&#xff1a;这题是要求每个子区间里面的最大值和最小值的差&#xff0c;我们一开始想的必然是纯暴力呀&#xff0c;但是一看这数据&#…...

学习测试10-3自动化 web自动化

web自动化 chrome驱动下载地址&#xff1a; https://registry.npmmirror.com/binary.html?pathchromedriver/ https://googlechromelabs.github.io/chrome-for-testing/#stable观察Google版本&#xff0c;下相应的驱动 运行代码试试&#xff0c;成功Google就会弹出 from se…...

安防视频监控EasyCVR视频汇聚平台修改配置后无法启动的原因排查与解决

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台基于云边端一体化架构&#xff0c;兼容性强、支持多协议接入&#xff0c;包括国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石云SD…...

爬虫学习2:爬虫爬取网页的信息与图片的方法

爬虫爬取网页的信息与图片的方法 爬取人物信息 import requestshead {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0" } # 这是get请求带参数的模式…...

MySQL定时备份数据,并上传到oss

1.环境准备 1.安装阿里云的ossutil 2.安装mysql 2.编写脚本 脚本内容如下 #!/bin/bash # 数据库的配置信息&#xff0c;根据自己的情况进行填写 db_hostlocalhost db_usernameroot db_passwordroot db_namedb_root # oss 存贮数据的bucket地址 bucket_namerbsy-backup-buck…...

极速删除 node_modules 仅3 秒()

今天教大家如何快速删除 node_modules 依赖的一个小秘诀&#xff0c;告别繁琐&#xff01;&#xff01;&#xff01; 前言 作为前端开发者&#xff0c;相信大家都曾经历过删除 node_modules 文件夹时的漫长等待。 尤其是在处理那些依赖库繁多的项目时&#xff0c;删除操作…...

vue this.$refs 动态拼接

业务需要&#xff0c;refs是不固定的 <vxe-grid refgridWarehouse v-bind"gridWarehouseOptions" v-if"tableHeight" :height"tableHeight":expand-config"{iconOpen: vxe-icon-square-minus, iconClose: vxe-icon-square-plus}"c…...

一次搞定!中级软件设计师备考通关秘籍

大家好&#xff0c;我是小欧&#xff01; 今天我们来聊聊软考这个话题。要是你准备参加计算机技术与软件专业技术资格&#xff08;软考&#xff09;&#xff0c;那么这篇文章就是为你量身定做的。话不多说&#xff0c;咱们直接进入正题。 什么是软考&#xff1f; 软考&#xf…...

第十六讲 python中的序列-列表简介-特点-常用方法-创建-添加-删除-访问-切片-排序-复制-反转

目录 1. 序列的本质和内存结构 2.列表 2.1 列表简介 2.2 列表的特点 2.3 列表对象的常用方法大全: 2.4 列表的创建 2.4.1 使用方括号 [] 2.4.2 使用 list() 函数 2.4.3 使用 range() 函数 2.4.3.1 range的基本用法 2.4.3.2 返回值 2.4.3.3 range的使用例子 2.4.3.4 range的使…...

大模型日报 2024-07-22

大模型日报 2024-07-22 大模型资讯 谷歌将在ICML 2024展示机器学习研究成果 摘要: 谷歌研究人员将在ICML 2024会议上展示他们在机器学习领域的探索&#xff0c;从理论到应用&#xff0c;构建解决深层问题的ML系统。 代理符号学习&#xff1a;优化AI系统符号组件的框架 摘要: 大…...

5分钟快速上手:如何用Video2X免费AI工具让老旧视频焕发4K新生

5分钟快速上手&#xff1a;如何用Video2X免费AI工具让老旧视频焕发4K新生 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/v…...

Argo CD 集成 Helmfile 插件:实现 GitOps 下复杂应用声明式部署

1. 项目概述与核心价值如果你正在使用 Argo CD 管理 Kubernetes 集群&#xff0c;并且你的应用清单是由 Helmfile 来编排的&#xff0c;那么travisghansen/argo-cd-helmfile这个项目很可能就是你一直在寻找的“粘合剂”。简单来说&#xff0c;它是一个专门为 Argo CD 设计的 He…...

Red Cabbage印相仅限Pro订阅者访问?不!本文泄露未公开的--raw+--v 6.2双模触发密钥(含Base64校验码验证)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Red Cabbage印相的技术本质与社区误读 Red Cabbage印相&#xff08;Red Cabbage Cyanotype&#xff09;并非传统蓝晒法的简单变体&#xff0c;而是一种基于花青素pH响应特性的光化学显影体系。其核心反…...

eFuse 的核心作用

它触及了设备安全性的核心机制——eFuse。 简而言之:一台已经烧录(blown)了 eFuse 的设备,其安全机制与未烧录 eFuse 的设备有本质区别,你之前在非 eFuse 设备上成功的代码修改(强制 check_key 返回 0)很可能在烧录了 eFuse 的设备上无效。 以下是详细解释: eFuse 的…...

BlueArchive-Cursors:开源鼠标主题的技术实现与扩展应用指南

BlueArchive-Cursors&#xff1a;开源鼠标主题的技术实现与扩展应用指南 【免费下载链接】BlueArchive-Cursors Custom mouse cursor theme based on the school RPG Blue Archive. 项目地址: https://gitcode.com/gh_mirrors/bl/BlueArchive-Cursors BlueArchive-Curso…...

影刀RPA高阶架构:告别“连点器”思维,内置原生指纹浏览器重塑全域店群防封底座

大家好&#xff0c;我是林焱&#xff0c;一名专注电商底层业务逻辑与企业级 RPA 自动化架构定制的独立开发者。 在技术社区和各大电商交流群里&#xff0c;我经常会遇到使用影刀 RPA 的开发者提出这样一个痛点&#xff1a;“林大&#xff0c;我用影刀写了一套逻辑非常严密的自…...

碧蓝航线脚本补丁Perseus:原生库的无偏移皮肤解锁技术实现

碧蓝航线脚本补丁Perseus&#xff1a;原生库的无偏移皮肤解锁技术实现 【免费下载链接】Perseus Azur Lane scripts patcher. 项目地址: https://gitcode.com/gh_mirrors/pers/Perseus 在移动游戏修改领域&#xff0c;实现版本兼容性一直是技术挑战的核心。Perseus项目通…...

从仿真波形到板卡调试:一次搞定Xilinx UltraScale+ FPGA DDR4读写测试全流程

从仿真波形到板卡调试&#xff1a;Xilinx UltraScale FPGA DDR4读写测试全流程实战指南 在FPGA系统设计中&#xff0c;DDR4内存接口的稳定性和性能往往是决定整个系统成败的关键因素。对于使用Xilinx UltraScale系列FPGA的工程师而言&#xff0c;从仿真验证到板卡调试的全流程掌…...

Steam游戏自动破解终极指南:3步实现DRM移除与离线游戏

Steam游戏自动破解终极指南&#xff1a;3步实现DRM移除与离线游戏 【免费下载链接】Steam-auto-crack Steam Game Automatic Cracker 项目地址: https://gitcode.com/gh_mirrors/st/Steam-auto-crack SteamAutoCrack是一款专业的Steam游戏自动破解工具&#xff0c;通过智…...

从ANSI到EBCDIC:跨越地域与时代的字符编码全景解析

1. 字符编码的前世今生&#xff1a;从ASCII到EBCDIC 第一次在Windows记事本里保存文件时&#xff0c;看到"ANSI"这个选项我就懵了——这玩意儿和ASCII有什么关系&#xff1f;后来在跨国项目里处理日文数据时&#xff0c;更被SJIS和EUC-JP搞得焦头烂额。字符编码就像…...