前端——html拖拽原理
文章目录
- ⭐前言
- ⭐draggable属性
- 💖 api
- 💖 单向拖动示例
- 💖 双向拖动示例
- ⭐总结
- ⭐结束

⭐前言
大家好,我是yma16,本文分享关于 前端——html拖拽原理。
vue3系列相关文章:
vue3 + fastapi 实现选择目录所有文件自定义上传到服务器
前端vue2、vue3去掉url路由“ # ”号——nginx配置
csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板
认识vite_vue3 初始化项目到打包
python_selenuim获取csdn新星赛道选手所在城市用echarts地图显示
让大模型分析csdn文章质量 —— 提取csdn博客评论在文心一言分析评论区内容
前端vue3——html2canvas给网站截图生成宣传海报
html draggable属性
dragabble属性是HTML5中新增加的属性,可以应用于任何HTML元素上,实现拖拽效果。当该属性设置为true时,元素就可以被拖拽。当元素被拖拽时,会触发dragstart、drag、dragend等事件。
例如:
<div draggable="true">拖拽我
</div>
上面的代码会在一个div元素上添加draggable属性,使其可拖拽。通过设置属性值为true,我们就可以实现该元素的拖拽效果。
⭐draggable属性
分解拖动动作
- 鼠标选择div
- 鼠标按住不放拖拽div
- 拖拽的div(源数据)在目标区域div外侧移动
- 拖拽的div(源数据)在目标区域div内侧移动
- 拖拽的div(源数据)在目标区域div内侧掉落
draggable属性:全局属性 draggable 是一种枚举 (en-US)属性,用于标识元素是否允许使用浏览器原生行为或 HTML 拖放操作 API 拖动。
true: 可以拖动
false: 禁止拖动
auto: 跟随浏览器定义是否可以拖动。
draggable 可以有如下取值:
true:表示元素可以被拖动
false:表示元素不可以被拖动
如果该属性没有设值,则默认值 为 auto,表示使用浏览器定义的默认行为。
注意:
这个属性是枚举类型 (en-US),而不是布尔类型。这意味着必须显式指定值为 true 或者 false,像 <img draggable> 这样的简写是不允许的。正确的用法是 <img draggable="false">。
💖 api
对象 | 事件 | 说明 |
---|---|---|
被拖动对象 | drag | 拖动时反复触发 drag ,事件在用户拖动元素或选择的文本时,每隔几百毫秒就会被触发一次。 |
被拖动对象 | dragstart | 拖动开始时触发,事件在用户开始拖动元素或被选择的文本时调用 |
被拖动对象 | dragend | 拖动结束时触发,事件在拖放操作结束时触发(通过释放鼠标按钮或单击 escape 键) |
目标对象 | drop | 事件在元素或文本选择被放置到有效的放置目标上时触发。为确保 drop 事件始终按预期触发,应当在处理 dragover 事件的代码部分始终包含 preventDefault() 调用 |
目标对象 | dragenter | 进入区域时触发,事件在可拖动的元素或者被选择的文本进入一个有效的放置目标时触发 |
目标对象 | dragover | 悬浮区域时触发,事件在可拖动的元素或者被选择的文本被拖进一个有效的放置目标时(每几百毫秒)触发 |
目标对象 | dragleave | 离开区域时触发,事件在拖动的元素或选中的文本离开一个有效的放置目标时被触发 |
💖 单向拖动示例
元素单方向拖动
<!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"><link href="style.css" rel="stylesheet" type="text/css" /><title>drag</title><style>html {height: 100%;width: 100%;background: #005AA7; /* fallback for old browsers */background: -webkit-linear-gradient(to bottom, #FFFDE4, #005AA7); /* Chrome 10-25, Safari 5.1-6 */background: linear-gradient(to bottom, #FFFDE4, #005AA7); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */}.container {text-align: center;padding: 64px;display: flex;justify-content: space-between;}.container-left {width: 40%;}.container-right {width: 40%;}.container-left-box {min-height: 100px;line-height: 100px;min-width: 400px;color:#fff;background: #b92b27; /* fallback for old browsers */background: -webkit-linear-gradient(to right, #1565C0, #b92b27); /* Chrome 10-25, Safari 5.1-6 */background: linear-gradient(to right, #1565C0, #b92b27); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */cursor: pointer;border-radius: 8px;}.container-right-box {min-height: 100px;line-height: 100px;min-width: 400px;color:#fff;background: #12c2e9; /* fallback for old browsers */background: -webkit-linear-gradient(to right, #f64f59, #c471ed, #12c2e9); /* Chrome 10-25, Safari 5.1-6 */background: linear-gradient(to right, #f64f59, #c471ed, #12c2e9); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */cursor: pointer;border-radius: 8px;}.dragging {opacity: .5;}.dragover{opacity: .5;}</style></head><body><div class="container"><div class="container-left"><div class="container-left-box" draggable="true" id="source">左侧可以拖动</div></div><div class="container-right"><div class="container-right-box dropzone" id="droptarget">可以拖到这里</div></div></div><script>// 配置项const config = {draged: null}function init() {console.log('window onload');/* 在可拖动的目标上触发的事件 */const source = document.getElementById("source");source.addEventListener("drag", (event) => {console.log("dragging");});source.addEventListener("dragstart", (event) => {// 保存被拖动元素的引用config.draged = event.target;// 设置为半透明event.target.classList.add("dragging");});source.addEventListener("dragend", (event) => {// 拖动结束,重置透明度event.target.classList.remove("dragging");});/* 在放置目标上触发的事件 */const target = document.getElementById("droptarget");target.addEventListener("dragover",(event) => {// 阻止默认行为以允许放置event.preventDefault();},false,);target.addEventListener("dragenter", (event) => {// 在可拖动元素进入潜在的放置目标时高亮显示该目标if (event.target.classList.contains("dropzone")) {event.target.classList.add("dragover");}});target.addEventListener("dragleave", (event) => {// 在可拖动元素离开潜在放置目标元素时重置该目标的背景if (event.target.classList.contains("dropzone")) {event.target.classList.remove("dragover");}});target.addEventListener("drop", (event) => {// 阻止默认行为(会作为某些元素的链接打开)event.preventDefault();// 将被拖动元素移动到选定的目标元素中if (event.target.classList.contains("dropzone")) {event.target.classList.remove("dragover");// 删除自身// config.draged.parentNode.removeChild(config.draged);event.target.appendChild(config.draged);}});}window.onload = init;</script></body></html>
拖动效果
💖 双向拖动示例
元素可以左右拖动
<!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"><link href="style.css" rel="stylesheet" type="text/css" /><title>drag</title><style>html {height: 100%;width: 100%;background: #005AA7;/* fallback for old browsers */background: -webkit-linear-gradient(to bottom, #FFFDE4, #005AA7);/* Chrome 10-25, Safari 5.1-6 */background: linear-gradient(to bottom, #FFFDE4, #005AA7);/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */}.container {text-align: center;padding: 64px;display: flex;justify-content: space-between;}.container-left {width: 40%;border: 1px solid #1565C0;border-radius: 8px;}.container-right {width: 40%;}.container-left-box {min-height: 100px;min-width: 100px;line-height: 100px;min-width: 400px;color: #fff;background: #b92b27;/* fallback for old browsers */background: -webkit-linear-gradient(to right, #1565C0, #b92b27);/* Chrome 10-25, Safari 5.1-6 */background: linear-gradient(to right, #1565C0, #b92b27);/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */cursor: pointer;border-radius: 8px;}.container-right-box {min-height: 100px;line-height: 100px;min-width: 400px;color: #fff;background: #12c2e9;/* fallback for old browsers */background: -webkit-linear-gradient(to right, #f64f59, #c471ed, #12c2e9);/* Chrome 10-25, Safari 5.1-6 */background: linear-gradient(to right, #f64f59, #c471ed, #12c2e9);/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */cursor: pointer;border-radius: 8px;}.dragging {opacity: .5;}.dragover {opacity: .5;}</style></head><body><div class="container"><div class="container-left dropzone" id='left-box'><div class="container-left-box" draggable="true" id="yma16">yma16</div></div><div class="container-right" id='right-box'><div class="container-right-box dropzone" id="csdn">csdn</div></div></div><script>// 配置项const config = {draged: null}const drag = (event) => {console.log("dragging");}const dragStart = (event) => {// 保存被拖动元素的引用config.draged = event.target;// 设置为半透明event.target.classList.add("dragging");}const dragEnd = (event) => {// 拖动结束,重置透明度event.target.classList.remove("dragging");}// 目标const dragOver = (event) => {// 阻止默认行为以允许放置event.preventDefault();}const dragLeave = (event) => {// 在可拖动元素离开潜在放置目标元素时重置该目标的背景if (event.target.classList.contains("dropzone")) {event.target.classList.remove("dragover");}}const dragEnter = (event) => {// 在可拖动元素进入潜在的放置目标时高亮显示该目标if (event.target.classList.contains("dropzone")) {event.target.classList.add("dragover");}}const drop = (event) => {// 阻止默认行为(会作为某些元素的链接打开)event.preventDefault();// 将被拖动元素移动到选定的目标元素中if (event.target.classList.contains("dropzone")) {event.target.classList.remove("dragover");// 删除自身config.draged.parentNode.removeChild(config.draged);// 添加元素event.target.appendChild(config.draged);}}function yma16ToLeft() {/* 在放置目标上触发的事件 */const target = document.getElementById("left-box");if(!target.classList.contains('dropzone')){target.classList.add('dropzone')}target.addEventListener("dragover",dragOver,false,);target.addEventListener("dragenter", dragEnter);target.addEventListener("dragleave", dragLeave);target.addEventListener("drop", drop);}function yma16ToRight() {const source = document.getElementById("yma16");source.addEventListener("drag", drag);source.addEventListener("dragstart", dragStart);source.addEventListener("dragend", dragEnd);/* 在放置目标上触发的事件 */const target = document.getElementById("csdn");target.addEventListener("dragover",dragOver,false,);target.addEventListener("dragenter", dragEnter);target.addEventListener("dragleave", dragLeave);target.addEventListener("drop", drop);}function init() {console.log('window onload');/* 在可拖动的目标上触发的事件 */yma16ToLeft()yma16ToRight()}window.onload = init;</script></body></html>
效果如下:
⭐总结
HTML的draggable属性可以将元素设置为可拖动的。它可以帮助我们实现拖拽功能,让用户可以将元素拖拽到指定的位置或者执行拖拽结束后的某些操作。draggable属性有以下几个取值:
-
draggable=“true”:表示元素可以被拖动。
-
draggable=“false”:表示元素不可以被拖动。
-
draggable=“auto”:表示元素可以被拖动,但是浏览器会根据元素类型和属性自动决定是否允许拖动。
在使用draggable属性时,需要注意以下几点:
-
可以设置辅助属性dataTransfer来传输数据。
-
可以设置ondragstart、ondrag、ondragenter、ondragover、ondragleave和ondragend等事件来实现一些特定操作。
-
需要在ondrop事件中阻止默认行为,否则拖拽的元素将会被打开或者在浏览器中进行导航。
综上所述,draggable属性是一个非常实用的属性,可以帮助我们实现一些常用的拖拽功能。
⭐结束
本文分享到这结束,如有错误或者不足之处欢迎指出!
👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 感谢你的阅读!
相关文章:

前端——html拖拽原理
文章目录 ⭐前言⭐draggable属性💖 api💖 单向拖动示例💖 双向拖动示例 ⭐总结⭐结束 ⭐前言 大家好,我是yma16,本文分享关于 前端——html拖拽原理。 vue3系列相关文章: vue3 fastapi 实现选择目录所有文…...

JVM 执行引擎篇
机器码、指令、汇编语言 机器码 各种用二进制编码方式表示的指令,叫做机器指令码。开始,人们就用它采编写程序,这就是机器语言。机器语言虽然能够被计算机理解和接受,但和人们的语言差别太大,不易被人们理解和记忆&a…...
js中数组对象去重的方法
前端面试题库 (面试必备) 推荐:★★★★★ 地址:前端面试题库 最近工作中需要用到数组对象去重的方法,我是怎么想也没想出来,今天稍微研究了一下,总算找到了2种方法。分享一下&…...

【送书活动四期】被GitHub 要求强制开启 2FA 双重身份验证,我该怎么办?
记得是因为fork了OpenZeppelin/openzeppelin-contracts的项目,之后就被GitHub 要求强制开启 2FA 双重身份验证了,一拖再拖,再过几天帐户操作将受到限制了,只能去搞一下了 目录 2FA是什么为什么要开启 2FA 验证GitHub 欲在整个平台…...
GO设计模式——13、享元模式(结构型)
目录 享元模式(Flyweight Pattern) 享元模式的核心角色: 优缺点 使用场景 注意事项 代码实现 享元模式(Flyweight Pattern) 享元模式(Flyweight Pattern)它通过共享对象来减少内存使用和提…...

Linux 网络协议
1 网络基础 1.1 网络概念 网络是一组计算机或者网络设备通过有形的线缆或者无形的媒介如无线,连接起来,按照一定的规则,进行通讯的集合( 缺一不可 )。 5G的来临以及IPv6的不断普及,能够进行联网的设备将会是越来越多(…...

【C语言】7-32 刮刮彩票 分数 20
7-32 刮刮彩票 分数 20 全屏浏览题目 切换布局 作者 DAI, Longao 单位 杭州百腾教育科技有限公司 “刮刮彩票”是一款网络游戏里面的一个小游戏。如图所示: 每次游戏玩家会拿到一张彩票,上面会有 9 个数字,分别为数字 1 到数字 9…...

交叉验证以及scikit-learn实现
交叉验证 交叉验证既可以解决数据集的数据量不够大问题,也可以解决参数调优的问题。 主要有三种方式: 简单交叉验证(HoldOut检验)、k折交叉验证(k-fold交叉验证)、自助法。 本文仅针对k折交叉验证做详细解…...
css实现头部占一定高度,内容区占剩余高度可滚动
上下布局: <div class"container"><header class"header">头部内容</header><div class"content">内容区域</div> </div>.container {display: flex;flex-direction: column;height: 100vh; /*…...

redis主从复制模式和哨兵机制
目录 第一章、主从复制模式1.1)Redis 主从复制模式介绍1.2)Redis 主从复制实现、 第二章、哨兵机制2.1)容灾处理之哨兵2.2)Sentinel 配置 第一章、主从复制模式 1.1)Redis 主从复制模式介绍 ①单点故障:数…...

WebStorm:Mac/Win上强大的JavaScript开发工具
WebStorm是JetBrains公司开发的针对Mac和Windows系统的JavaScript开发工具。它为开发者提供了一站式的代码编辑、调试、测试和版本控制等功能,帮助你更高效地进行Web开发。新版本的WebStorm 2023在性能和用户体验方面都做出了重大改进,让你的JavaScript开…...
传世SUN引擎如何安装
大家在搭建的时候一定要理清思路一步一步来,否则一步错步步错。下面跟大家说一下搭建的顺序以及细节。 第一步:首先下载DBC2000进行安装,并按照里面的说明设置好。1、请把压缩包释放到D:\QMirServer目录下。2、在控制面板里找到BDC Administ…...
vue 生命周期
什么是生命周期,有什么作用 定义:vue 实例从创建到销毁的过程,在某个特定的位置会触发一个回调函数 作用:供开发者在生命周期的特定阶段执行相关的操作 生命周期分别有几个阶段 有四个阶段,每个阶段有两个钩子&…...
多开工具对应用程序性能的影响与优化
多开工具对应用程序性能的影响与优化 摘要: 随着计算机技术的不断发展,多开工具逐渐成为一种常见的软件应用。然而,使用多开工具可能会对应用程序的性能产生一定的影响。本文将探讨多开工具对应用程序性能的影响,并提供一些优化方…...
G1 GC基本逻辑
1 MixedGC基本过程 在G1GC中,有两种主要的垃圾回收过程:Young GC和Mixed GC。这两者都是为了回收堆内存中的垃圾对象,但是他们关注的区域和工作方式有所不同。 Young GC: Young GC主要负责回收Young Generation(包括…...

nvidia安装出现7-zip crc error解决办法
解决办法:下载network版本,重新安装。(选择自己需要的版本) 网址:CUDA Toolkit 12.3 Update 1 Downloads | NVIDIA Developer 分析原因:local版本的安装包可能在下载过程中出现损坏。 本人尝试过全网说的…...

(C语言实现)高精度除法 (洛谷 P2005 A/B Problem II)
前言 本期我们分享用C语言实现高精度除法,可通过该题测试点我点我,洛谷 p2005。 那么话不多说我们开始吧。 讲解 大家还记不记得小学的时候我们是怎么做除法的?我们以1115为例。 我们的高精度除法也将采用这个思路进行,分别用两…...

【AI】Windows环境安装GroundingDINO
Grounding DINO简单来说,它可以根据文字描述检测指定目标。此外,当Grounding DINO与stable diffusion结合,便可以实现更神奇的功能–自动P图。在专业领域中,GroundingDINO可以用来进行遥感影像解译,可以减少人工工作量…...

【Node.js】基础梳理 6 - MongoDB
写在最前:跟着视频学习只是为了在新手期快速入门。想要学习全面、进阶的知识,需要格外注重实战和官方技术文档,文档建议作为手册使用 系列文章 【Node.js】笔记整理 1 - 基础知识【Node.js】笔记整理 2 - 常用模块【Node.js】笔记整理 3 - n…...
.NET8 依赖注入
依赖注入(Dependency Injection,简称DI)是一种设计模式,用于解耦组件(服务)之间的依赖关系。它通过将依赖关系的创建和管理交给外部容器来实现,而不是在组件(服务)内部直…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...