JavaScript鼠标拖放(Drag and Drop)

🧑‍🎓 个人主页:《爱蹦跶的大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 中的实现,涵盖初始化、跟踪拖放过程、访问数据等完整功能。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探索前端开发框架:React、Angular 和 Vue 的对决(一)

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

linux找回root密码(CentOS7.6)

首先,启动系统,进入开机界面,在界面中按“e”进入编辑界面。如图 进入编辑界面,使用键盘上的上下键把光标往下移动,找到以““Linux16”开头内容所在的行数”,在行的最后面输入:init/bin/sh。如…

位图布隆过滤器

位图&&布隆过滤器 位图位图的实现位图优缺点关于位图的题目位图的应用 布隆过滤器提出原因布隆过滤器概念操作插入查找删除 bloom优缺点关于bloom的题目实现 哈希切割问题 位图 位图:使用比特位来表示某种状态。比特位为0表示不存在,为1表示存在…

C语言内存函数:memcpy、memcat、memmove介绍和模拟实现(实用性高,建议三连收藏)

目录 1.memcpy函数 1.1函数介绍 1.2函数示范使用 1.3函数的模拟实现 1.4补充 2.memmove函数 2.1函数介绍 2.2函数的使用示范 2.3函数的模拟实现 3.memcmp(内存比较函数) 3.1函数介绍 3.2函数的示范使用,有趣的例子 4.函数补充memset(内存…

Visual Studio 最新版安装教程

Visual Studio简介 Visual Studio是一个集成开发环境(IDE),广泛应用于.NET和C工作负载以及许多其他语言和框架的开发。它提供了一套完整的工具集,包括UML工具、代码管控工具、集成开发环境(IDE)等&#xff…

c++重载、隐藏和覆盖

重载 函数名字相同&#xff0c;但参数列表或者返回值不同一组函数要重载必须处在同一作用域中 class Base { public:Base(int data0):m_a(data){}void show(){cout<<"Base::show()"<<endl;}void show(int){cout<<"Base:show(int)"<&l…

Opencv(C++)学习 TBB与OPENMP的加速效果实验与ARM上的实践(二)

在上一篇文章中&#xff0c;我们成功验证了Intel Threading Building Blocks (TBB) 与 OpenMP 在多线程并行处理方面的加速潜力。为了更深入地理解这些技术在实际应用场景中的效能提升&#xff0c;接下来我们将目光转向目标开发板环境&#xff0c;进一步探究这两种框架在嵌入式…

快速排序

思想&#xff1a;分而治之&#xff1b; 确定好基准值然后在两侧递归调用,记好模版就好了 #include<bits/stdc.h> using namespace std; int n; const int N1e610; int q[N]; void quick_sort(int q[],int l,int r) {if(l>r)return ;int xq[l],il-1,jr1;while(i<j…

js数组和字符串之间的转换方式以及数组的一些方法

一、数组和字符串之间的转换方式 1&#xff09;将字符串切割成字符串数组—stringObject.split(separator, howmany) seperator-----字符串、正则表达式&#xff0c;必需 howmany------指定返回的数组的最大长度&#xff0c;可省略&#xff0c;省略后全量返回 源代码 var str&q…

自研人工智能小工具-小蜜蜂(国外ChatGpt的平替)

国内有非常多好用的人工智能工具&#xff0c;但均无法完全替代国外ChatGpt。 ChatGPT相较于其他国内工具的优势在于以下几点&#xff1a; 创新的语言生成能力&#xff1a;ChatGPT是由OpenAI开发的先进的自然语言生成模型&#xff0c;它采用了大规模的预训练和精细调整方法。因此…

揭秘远程控制APP的便捷之美!

在这个科技日新月异的时代&#xff0c;我们的生活被各种手机软件所包围。几乎每个人都有一个甚至多个手机&#xff0c;你是否也有遇到过需要远程操作自己某一台手机的场景呢&#xff1f;今天&#xff0c;我要向大家推荐一款神奇的手机远程操作神器&#xff0c;让你可以随时随地…

格式化日期注解@JsonFormat的使用和TimeZone时区问题

JsonFormat的使用 目的 为了便于date类型字段的序列化和反序列化&#xff0c;需要在数据结构的Date、Timestamp、DateTime类型的字段上用JsonFormat注解进行注解 使用 JsonFormat注解是一个时间格式化注解&#xff0c;比如我们存储在mysql中的数据是date类型的&#xff0c;当…

聊聊比特币----比特币地址

⽐特币地址是⼀个标识符&#xff08;帐号&#xff09;&#xff0c;包含27-34个字母数字拉丁字符&#xff08;0&#xff0c;O&#xff0c;I除外&#xff09;。地址可以以QR码形式表⽰&#xff0c;是匿名的&#xff0c;不包含关于所有者的信息。 地址⽰例&#xff1a;14qViLJfdG…

树状数组复习

基本原理 树状数组的原理简单来说就是利用二进制拆分区间 我们可以对一个数进行二进制分解&#xff0c;最多分解成log(x)个数&#xff0c;同样我们可以对[1,n]这个区间进行分解。也是最多log段&#xff0c;每次修改时我们维护受到影响的区间&#xff0c;然后查询时用这log个区…

ele-h5项目使用vue3+vite开发:第四节、业务组件-SearchView组件开发

需求分析 展示切换动画搜索框输入文字&#xff0c;自动发送请求搜索结果展示搜索状态维护历史搜索展示&#xff0c;点击历史搜索后发送请求历史搜索更多切换动画效果 <script setup lang"ts"> import OpSearch from /components/OpSearch.vue import { ref } f…

前端JavaScript篇之对JSON的理解

目录 对JSON的理解 对JSON的理解 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;它以易读易写的文本形式表示结构化数据&#xff0c;比较适合用来在不同的应用程序或平台之间传递数据。 简单来说&#xff0c;JSON就像是一种…

LangChain 81 LangGraph 从入门到精通三

LangChain系列文章 LangChain 60 深入理解LangChain 表达式语言23 multiple chains链透传参数 LangChain Expression Language (LCEL)LangChain 61 深入理解LangChain 表达式语言24 multiple chains链透传参数 LangChain Expression Language (LCEL)LangChain 62 深入理解Lang…

Git使用命令大全

命令大全参考阮一峰的博客&#xff0c;根据自己的使用习惯作了调整。 Git常用命令 其他常用的命令 配置Git # 显示当前的Git配置 $ git config --list# 编辑Git配置文件 $ git config -e [--global]# 设置提交代码时的用户信息 $ git config [--global] user.name "[nam…

JAVA工厂方法模式详解

工厂方法模式 工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 在工厂模式中&#xff0c;我们在创建对象时不会对客户端暴露创建逻辑&#xff0c;并且是通过…

如何结合ChatGPT生成个人魔法咒语词库

3.6.1 ChatGPT辅助力AI绘画 3.6.1.1 给定主题让ChatGPT直接描述 上面给了一个简易主题演示一下&#xff0c;这是完全我没有细化的提问&#xff0c;然后把直接把这些关键词组合在一起。 关键词&#xff1a; 黄山的美景&#xff0c;生机勃勃&#xff0c;湛蓝天空&#xff0c;青…