JavaScript鼠标拖放(Drag and Drop)

news2024/9/23 3:22:58

🧑‍🎓 个人主页:《爱蹦跶的大A阿》

🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》

​ 

✨ 前言

        拖放是现代界面不可或缺的交互方式之一。本文将介绍如何用JavaScript来实现元素的拖放功能。

        我们首先需要准备拖放事件,之后跟踪拖动过程中鼠标位置,计算元素的新坐标。我们也可以实现拖放目标,在元素ENTER和LEAVE 时做出响应。最后,可以在放置时传递数据。

        掌握拖放接口不仅可以优化交互,也可以大展创意,制作游戏等应用。让我们开始学习拖放之旅吧!

✨ 正文

本文介绍 JavaScript 实现元素的拖放功能。

开始拖放

用于启动拖动的事件是 ondragstart:

ball.ondragstart = function() {
  return false; // 允许拖放
};

我们还需要 ondrag 事件来实现拖放过程中元素的移动。

在拖动过程中

ball.ondrag = function(event) { // 移动 ball 到新的坐标 ball.style.left = event.clientX + 'px'; ball.style.top = event.clientY + 'px'; };

通过事件对象的 clientX/clientY 属性获取鼠标坐标来移动被拖动元素。

实现目标放置

当拖动的元素进入目标元素时候,会触发目标元素的 ondragenter 事件:

target.ondragenter = function(event) {
  // 高亮目标元素 (change bg color)
  event.target.style.background = 'pink';
};

当拖动退出目标元素时,ondragleave 事件被触发。

最后元素松开鼠标时,会触发 ondrop 事件来执行放置操作。

数据传递

可以使用 event.dataTransfer 对象在拖动源(source)和放置目标(target)之间传递数据:

// 拖动源
ball.ondragstart = function(event) {
  event.dataTransfer.setData('text', 'ball data'); 
};

// 放置目标
field.ondrop = function(event) {
  let data = event.dataTransfer.getData('text');
  // Do something with the data
};

修正定位

在元素拖动代码示例中,球在移动时,球的中心始终位于鼠标指针下方:

ball.style.left = pageX - ball.offsetWidth / 2 + 'px';
ball.style.top = pageY - ball.offsetHeight / 2 + 'px';

不错,但这存在副作用。要启动拖放,我们可以在球上的任意位置 mousedown。但是,如果从球的边缘“抓住”球,那么球会突然“跳转”以使球的中心位于鼠标指针下方。

如果我们能够保持元素相对于鼠标指针的初始偏移,那就更好了。

例如,我们按住球的边缘处开始拖动,那么在拖动时,鼠标指针应该保持在一开始所按住的边缘位置上。

让我们更新一下我们的算法:

  1. 当访问者按下按钮(mousedown)时 —— 我们可以在变量 shiftX/shiftY 中记住鼠标指针到球左上角的距离。我们应该在拖动时保持这个距离。

    我们可以通过坐标相减来获取这个偏移:

    // onmousedown
    let shiftX = event.clientX - ball.getBoundingClientRect().left;
    let shiftY = event.clientY - ball.getBoundingClientRect().top;
  2. 然后,在拖动球时,我们将鼠标指针相对于球的这个偏移也考虑在内,像这样:

    // onmousemove
    // 球具有 position: absolute
    ball.style.left = event.pageX - shiftX + 'px';
    ball.style.top = event.pageY - shiftY + 'px';

能够更好地进行定位的最终代码: 

ball.onmousedown = function(event) {

  let shiftX = event.clientX - ball.getBoundingClientRect().left;
  let shiftY = event.clientY - ball.getBoundingClientRect().top;

  ball.style.position = 'absolute';
  ball.style.zIndex = 1000;
  document.body.append(ball);

  moveAt(event.pageX, event.pageY);

  // 移动现在位于坐标 (pageX, pageY) 上的球
  // 将初始的偏移考虑在内
  function moveAt(pageX, pageY) {
    ball.style.left = pageX - shiftX + 'px';
    ball.style.top = pageY - shiftY + 'px';
  }

  function onMouseMove(event) {
    moveAt(event.pageX, event.pageY);
  }

  // 在 mousemove 事件上移动球
  document.addEventListener('mousemove', onMouseMove);

  // 放下球,并移除不需要的处理程序
  ball.onmouseup = function() {
    document.removeEventListener('mousemove', onMouseMove);
    ball.onmouseup = null;
  };

};

ball.ondragstart = function() {
  return false;
};

 以上介绍了拖放功能从准备到完成的完整流程。希望对大家实现拖放有帮助! 

✨ 结语

        拖放是一项强大的功能,可以优化交互,增强用户体验。本文详细介绍了拖放在 JavaScript 中的实现,涵盖初始化、跟踪拖放过程、访问数据等完整功能。

        希望这篇博客可以帮助大家深入理解拖放接口,并能应用到实际项目中。如果在学习或运用中有任何问题,欢迎在评论区与我讨论。

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

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

相关文章

Redis核心技术与实战【学习笔记】 - 19.Pika:基于SSD实现大容量“Redis”

前言 随着业务数据的增加(比如电商业务中,随着用户规模和商品数量的增加),就需要 Redis 能保存更多的数据。你可能会想到使用 Redis 切片集群,把数据分散保存到不同的实例上。但是这样做的话,如果要保存的…

C# 程序不显示控制台

C# 程序不显示控制台。 C# 使用代码隐藏控制台。 文章目录 代码效果 代码 class Program {// 导入kernel32.dll库中的AllocConsole函数[DllImport("kernel32.dll")]static extern bool AllocConsole();// 导入kernel32.dll库中的FreeConsole函数[DllImport("k…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Menu组件

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Menu组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Menu组件 TextClock组件通过文本将当前系统时间显示在设备上。支持不同时区的时间…

Mysql运维篇(四) MySQL常用命令

一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人。如有侵权,请留言,我及时删除! 一、MySQL命令速查表 https://www.cnblogs.com/pyng/p/15560059.html Mysql DBA运维命令大全 - 墨…

记录Git无法连接Github(443报错)的一种可能——代理问题

参考文章: Git安装配置与使用(超级详细)_git配置-CSDN博客 github代理报错_valueerror: unable to determine socks version from-CSDN博客 速通 如果在使用 git 时遇到了这样的报错: OpenSSL SSL_connect: SSL_ERROR_SYSCAL…

[office] excel表格怎么绘制股票的CCI指标- #媒体#学习方法#笔记

excel表格怎么绘制股票的CCI指标? excel表格怎么绘制股票的CCI指标?excel表格中想要绘制一个股票cci指标,该怎么绘制呢?下面我们就来看看详细的教程,需要的朋友可以参考下 CCI指标是一种在股票,贵金属,货…

嵌入式软件工程师面试题——嵌入式专题 (五十二)

说明: 面试群,群号: 228447240面试题来源于网络书籍,公司题目以及博主原创或修改(题目大部分来源于各种公司);文中很多题目,或许大家直接编译器写完,1分钟就出结果了。但…

【新书推荐】5.2 位运算符

本节必须掌握的知识点: 位运算 示例十七 代码分析 汇编解析 5.2.1 位运算 位运算符如表5-2所示: 运算符 作用 示例 & 按位与 两个操作数同时为1,结果为1; | 按位或 两个操作数只要有一个为1,结果就为1&a…

Apollo配置中心之Server端

一、通知机制 二、架构思考 1、配置变更如何通知客户端? (1)如何建立长轮询? 2、客户端如何拉取数据? (1)如何拉取数据? 3、如何发现变更数据? (1&…

全国医院及文体设施相关情况数据,shp+excel格式,多字段可查询,所见即所得

基本信息. 数据名称: 全国医院及文体设施相关情况数据 数据格式: shpexcel 数据几何类型: 面 数据坐标系: WGS84 数据来源:网络公开数据 数据字段: 序号字段名称字段说明1province省级名称2city城市名称3city_dm城市代码4tsgcss2020公共图书馆图…

vulhub中 Apache Airflow Celery 消息中间件命令执行漏洞复现(CVE-2020-11981)

Apache Airflow是一款开源的,分布式任务调度框架。在其1.10.10版本及以前,如果攻击者控制了Celery的消息中间件(如Redis/RabbitMQ),将可以通过控制消息,在Worker进程中执行任意命令。 1.利用这个漏洞需要控…

[基础IO]文件描述符{重定向/perror/磁盘结构/inode/软硬链接}

文章目录 1. 再识重定向2.浅谈perror()3.初始文件系统4.软硬链接 1. 再识重定向 图解./sf > file.txt 2>&1 1中内容拷贝给2 使得2指向file 再学一个 把file的内容传给cat cat拿到后再给file2 2.浅谈perror() open()接口调用失败返回-1,并且错误码errno被适当的设置,…

Hive 主要内容一览

Hive架构 用户接口:Client CLI(command-line interface)、JDBC/ODBC(jdbc访问hive) 元数据:Metastore 元数据包括:表名、表所属的数据库(默认是default)、表的拥有者、列/分区字段、表的类型&am…

CTF(5)

一、[SWPUCTF 2021 新生赛]ez_caesar 1、题目 import base64 def caesar(plaintext):str_list list(plaintext)i 0while i < len(plaintext):if not str_list[i].isalpha():str_list[i] str_list[i]else:a "A" if str_list[i].isupper() else "a"…

vulhub中Adminer远程文件读取漏洞复现(CVE-2021-43008)

Adminer是一个PHP编写的开源数据库管理工具&#xff0c;支持MySQL、MariaDB、PostgreSQL、SQLite、MS SQL、Oracle、Elasticsearch、MongoDB等数据库。 在其版本1.12.0到4.6.2之间存在一处因为MySQL LOAD DATA LOCAL导致的文件读取漏洞。 参考链接&#xff1a; https://gith…

端到端实现高精地图重建(TopoNet解读和横评)

论文出处 [2304.05277] Graph-based Topology Reasoning for Driving Scenes (arxiv.org)https://arxiv.org/abs/2304.05277 TopoNet TopoNet的目标是从车辆上安装的多视角摄像头获取图像&#xff0c;感知实体并推理出驾驶场景的拓扑关系&#xff0c;实现端到端预测&#xf…

2017年苏州大学837复试机试C/C++

2017年苏州大学复试机试 要求 要求用C/C编程&#xff1b;对程序中必要的地方进行注释。上机规则 请在电脑桌面上新建一个文件夹文件夹名为考试姓名&#xff08;中文&#xff09;&#xff1b;考试完毕后&#xff0c;将所编写的文件放在上述文件中。 第一题&#xff08;20分&…

Node.js-1

Node.js 简介 定义&#xff1a;Node.js 是一个跨平台 JavaScript 运行环境&#xff0c;使开发者可以搭建服务器端的 JavaScript 应用程序 为什么 Node.js 能执行 JS 代码&#xff1a; Chrome 浏览器能执行 JS 代码&#xff0c;依靠的是内核中的 V8引擎&#xff08;即&#x…

react 使用react-seamless-scroll实现无缝滚动

文章目录 1. 实现无缝滚动效果2. react-seamless-scroll 无缝滚动案例介绍3. react 项目集成3.1 项目引入 cssSeamlessScroll 滚动组件3.2 完整代码3.2.1 newBet.tsx 代码3.2.2 index.module.scss 1. 实现无缝滚动效果 实现单步向下滚动点击更多展开&#xff0c;收起&#xff0…

[Angular 基础] - Angular 渲染过程 组件的创建

[Angular 基础] - Angular 渲染过程 & 组件的创建 之前的笔记为了推进度写的太笼统了&#xff08;只有功能没有其他&#xff09;&#xff0c;当时学的时候知道是什么东西&#xff0c;但是学完后重新复习发现有些内容就记不清了&#xff0c;所以重新用自己的语言总结一下 …