前端——html拖拽原理

news2024/11/16 7:53:18

文章目录

    • ⭐前言
    • ⭐draggable属性
      • 💖 api
      • 💖 单向拖动示例
      • 💖 双向拖动示例
    • ⭐总结
    • ⭐结束

yma16-logo

⭐前言

大家好,我是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博客评论在文心一言分析评论区内容
html draggable属性
dragabble属性是HTML5中新增加的属性,可以应用于任何HTML元素上,实现拖拽效果。当该属性设置为true时,元素就可以被拖拽。当元素被拖拽时,会触发dragstart、drag、dragend等事件。

例如:

<div draggable="true">
  拖拽我
</div>

上面的代码会在一个div元素上添加draggable属性,使其可拖拽。通过设置属性值为true,我们就可以实现该元素的拖拽效果。

⭐draggable属性

分解拖动动作

  1. 鼠标选择div
  2. 鼠标按住不放拖拽div
  3. 拖拽的div(源数据)在目标区域div外侧移动
  4. 拖拽的div(源数据)在目标区域div内侧移动
  5. 拖拽的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>

拖动效果
single-drag-demo

💖 双向拖动示例

元素可以左右拖动

<!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属性有以下几个取值:

  1. draggable=“true”:表示元素可以被拖动。

  2. draggable=“false”:表示元素不可以被拖动。

  3. draggable=“auto”:表示元素可以被拖动,但是浏览器会根据元素类型和属性自动决定是否允许拖动。

在使用draggable属性时,需要注意以下几点:

  1. 可以设置辅助属性dataTransfer来传输数据。

  2. 可以设置ondragstart、ondrag、ondragenter、ondragover、ondragleave和ondragend等事件来实现一些特定操作。

  3. 需要在ondrop事件中阻止默认行为,否则拖拽的元素将会被打开或者在浏览器中进行导航。

综上所述,draggable属性是一个非常实用的属性,可以帮助我们实现一些常用的拖拽功能。

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!
sence

👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 感谢你的阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1284695.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安装you-get(mac)

1、首先要有python环境 2、更新pip python -m pip install --upgrade pip 3、安装you-get pip install you-get;

面试多线程八股文十问十答第二期

面试多线程八股文十问十答第二期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1.进程和线程的区别 概念不同&#xff1a;进程是操作系统中的一个独立执行单元&a…

redis 安装在liunx安装和常用文件配置

文章目录 安装配置文件设置测试启动服务连接服务 安装 1.官网下载压缩包: https://redis.io/download/ 2.将压缩包上传到Linux环境中 解压: tar -xvf redis-xxxxx 3.liunx 需要c的环境 yum -y install gcc-c4.进入redis文件夹 make && make install5.推荐不是必须…

【滤波第二期】中值滤波的原理和C代码

中值滤波是一种非线性数字滤波技术&#xff0c;主要应用于信号处理和图像处理领域&#xff0c;用于减小信号中的噪声和离群值。中值滤波的核心思想是通过计算一组数据点的中间值&#xff0c;以抑制脉冲噪声等离群值的影响&#xff0c;从而实现信号的平滑处理。 1&#xff0c;中…

spring cloud nacos整合gateway

文章目录 gateway快速入门创建gateway服务&#xff0c;引入依赖编写启动类编写基础配置和路由规则重启测试网关路由的流程图 断言工厂过滤器工厂路由过滤器的种类请求头过滤器默认过滤器总结 全局过滤器全局过滤器作用自定义全局过滤器过滤器执行顺序 跨域问题什么是跨域问题解…

浅谈Django之单元测试

一、什么是单元测试 单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。如果测试通过则说明我们这个函数或功能能够正常工作&#xff0c;如果失败要么测试用例不正确&#xff0c;要么函数有bug需要修复。 二、如何使用单元测试 from django.test imp…

使用UART和USART在STM32上进行双向通信

在本文中&#xff0c;我们将深入了解如何在STM32上使用UART&#xff08;通用异步收发传输器&#xff09;和USART&#xff08;通用同步异步收发传输器&#xff09;实现双向通信。UART和USART是常见的串口通信协议&#xff0c;通常用于与其他设备进行数据传输。我们将重点介绍如何…

抓取Chrome所有版本密码

谷歌浏览器存储密码的方式 在使用谷歌浏览器时,如果我们输入某个网站的账号密码,他会自动问我们是否要保存密码,以便下次登录的时候自动填写账号和密码 在设置中可以找到登录账户和密码 也可以直接看密码,不过需要凭证 这其实是windows的DPAPI机制 DPAPI Data Protection Ap…

ESP32 freeRTOS笔记 参数传递、任务优先级

一、四种参数传递方式 1.1 整数传递 使用 (void *) 任何类型传递参数&#xff0c;通过地址传递给任务。 #include <stdio.h> #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h"void myTask(void *pvP…

leetcode算法之栈

目录 1.删除字符串中的所有相邻重复项2.比较含退格的字符串3.基本计算器II4.字符串解码5.验证栈序列 1.删除字符串中的所有相邻重复项 删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {string ret;//使用数组模拟栈操作for(auto …

element的el-date-picker时间控件,限制选择范围区间天数并且当前之后的日期不可选

element的el-date-picker时间控件&#xff0c;限制选择范围区间天数并且当前之后的日期不可选 HTML部分代码 <el-date-pickerv-model"dateRange"type"datetimerange"value-format"yyyy-MM-dd HH:mm:ss"range-separator"至"start-p…

Python小案例:打印10以内的素数

解析 1、利用循环控制范围&#xff08;1,100&#xff09; 2、通过循环判断素数 3、利用标记法进行打印素数 代码 #求1——100之间的素数 for i in range(2,101):is_primeNum Truefor j in range(2,i):if i%j 0:# print(f"{i}不是素数")is_primeNum Falseif is_…

3D Web可视化平台助力Aras开发PLM系统:提供数据访问、可视化和发布功能

HOOPS中文网慧都科技是HOOPS全套产品中国地区指定授权经销商&#xff0c;提供3D软件开发工具HOOPS售卖、试用、中文试用指导服务、中文技术支持。http://techsoft3d.evget.com/ Aras是一个面向数字化工业应用的开放性平台&#xff0c;帮助世界领先的复杂互联产品制造商转变其产…

文字处理工具Word mac软件特点

Microsoft Word mac是一款文字处理软件。它是 Microsoft office 套件的一部分&#xff0c;已广泛用于创建、编辑和格式化文本文档。 Word mac软件特点 改进的协作工具&#xff1a;使用 Microsoft Word 2021&#xff0c;多个用户可以同时处理一个文档&#xff0c;从而更轻松地与…

(华为)网络工程师教程笔记(网工教程)网工入门——3、静态路由路由表的配置

参考文章&#xff1a;【全236集】网络工程师从基础入门到进阶必学教程&#xff01;通俗易懂&#xff0c;2023最新版&#xff0c;学完即可就业&#xff01;网工入门_华为认证_HCIA_HCIP_数据通信_网工学习路线 文章目录 13. 网工入门10-静态路由&#xff08;路由表的配置&#x…

STM32通用定时器

本文实践&#xff1a;实现通过TIM14_CH1输出PWM&#xff0c;外部显示为呼吸灯。 通用定时器简介 拥有TIM2~TIM5、TIM9~TIM14 一共10个定时器&#xff0c;具有4路独立通道&#xff0c;可用于输入捕获、输出比 较&#xff0c;同时包含了基本定时去的所有功能。 通用定时器的结…

Educational Codeforces Round 159 (Rated for Div. 2)(B 二分贪心 Cgcd D二分+前缀和 E字典树)

A - Binary Imbalance 有只要在01之间插入就能制造无限个0&#xff0c;没有0就统计0 1个数即可 #include<bits/stdc.h> using namespace std; const int N 110010,mod998244353; #define int long long typedef long long LL; typedef pair<int, int> PII; const…

java学习part34collect和map

153-集合框架-数组的特点、弊端与集合框架体系介绍_哔哩哔哩_bilibili 1.以前的数组 2.常用 3.Collection add只能加object&#xff0c;如果有基本类型会装箱 3.2集合和数组转换 3.3往集合添加对象的注意事项 4.迭代器 容易越界 一般不用 常用好用 5.for each 类似c的for( …

vue3 vue-router编程式导航(二)

文章目录 一、跳转到指定路径1. query传参2. Params传参 二、前进/后退三、替换当前页 Vue Router提供了强大且灵活的编程式导航功能&#xff0c;能够通过代码来控制路由的切换和跳转。本篇博客将介绍如何在Vue 3应用程序中使用Vue Router进行编程式导航。 一、跳转到指定路径…

Proteus仿真--基于51单片机的DS18B20温度采集及报警

本文介绍基于DS18B20温度采集及报警的仿真设计&#xff08;完整仿真源文件及代码见文末链接&#xff09; 仿真图如下 其中温度传感器选用DS18B20器件&#xff0c;主要用于获取温度数据并上传&#xff0c;温度显示选用数码管&#xff0c;报警模块选用蜂鸣器 仿真运行视频 Pr…