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

前端中的拖拽知识

概述

本文主要介绍前端中拖拽相关的知识以及如何在 vue3 工程里实现拖拽指令。

前端中的拖拽

前端中的拖拽功能是一种交互设计,允许用户通过鼠标或触摸操作移动页面上的元素到不同的位置。这一功能的实现涉及 HTMLCSSJavaScript 的综合运用。

HTML元素拖拽
  • 拖拽元素

HTML 元素有一个draggable属性,接受一个布尔值,默认值为false(不可拖拽)。

<div draggable="true">我是可拖动的</div>
  • 事件处理

拖拽功能的实现依赖于几个关键的拖放事件:

  • dragstart: 当用户开始拖动元素时触发,可以在这里设置数据传输(如拖动的数据类型和值)。

  • drag: 元素正在被拖动时连续触发。

  • dragend: 用户释放鼠标,结束拖动时触发。

  • dragenterdragover: 当拖动的元素进入或停留在目标区域时触发。通常需要阻止这两个事件的默认行为,以允许元素被放置。

  • drop: 在拖动元素被释放到有效目标时触发,是接收拖动数据并执行相应操作的地方。

示例效果

效果如下:
在这里插入图片描述

核心代码

代码如下:

dragClass.addEventListener("dragstart", (e) => {
  const node = e.target.cloneNode(true);
  e.dataTransfer.setData("cloneNode", node.outerHTML);
});

dragClass.addEventListener("dragend", (e) => {
  e.dataTransfer.clearData();
});

dropDom.addEventListener("dragover", (e) => {
  if (e.target.className == "draggable") {
    e.preventDefault();
  }
});

dropDom.addEventListener("drop", (e) => {
  e.preventDefault();
  const node = e.dataTransfer.getData("cloneNode");
  e.target.innerHTML = node;
  const originCellNode = e.dataTransfer.getData("text/html");
  if (originCellNode) {
    originCellNode.removeChild(originCellNode);
  }
  e.dataTransfer.clearData("cloneNode");
});

dragTableCell.addEventListener("dragstart", (e) => {
  const node = e.target.cloneNode(true);
  e.dataTransfer.setData("cloneNode", node.outerHTML);
  e.dataTransfer.setData("text/html", e.target.parentNode.outerHTML);
});
参考地址

参考地址:https://github.com//blog/blob/main/docs/Demo/03.drag.html

vue3 拖拽指令封装

在 vue3 中实现组件的拖拽,可以封装一个拖拽指令,再需要进行拖拽的组件上加上v-drag即可。

拖拽指令实现实现如下:

export const drag = {
  mounted(el) {
    el.style.position = "absolute";
    el.style.cursor = "move";

    let startX, startY, initialX, initialY;

    const dragStart = (e) => {
      startX = e.clientX;
      startY = e.clientY;
      initialX = el.offsetLeft;
      initialY = el.offsetTop;

      document.addEventListener("mousemove", dragMove);
      document.addEventListener("mouseup", dragEnd);
    };

    const dragMove = (e) => {
      const dx = e.clientX - startX;
      const dy = e.clientY - startY;
      const newX = initialX + dx;
      const newY = initialY + dy;

      const maxX = window.innerWidth - el.offsetWidth;
      const maxY = window.innerHeight - el.offsetHeight;

      /**边界检查 */
      el.style.left = `${Math.min(Math.max(newX, 0), maxX)}px`;
      el.style.top = `${Math.min(Math.max(newY, 0), maxY)}px`;
    };

    const dragEnd = () => {
      document.removeEventListener("mousemove", dragMove);
      document.removeEventListener("mouseup", dragEnd);
    };

    el.addEventListener("mousedown", dragStart);
  },
};

http://www.kler.cn/a/447004.html

相关文章:

  • windows下搭建本地sofa-registry
  • 电商数据流通的未来:API接口的智能化与自动化趋势
  • Web3.0安全开发实践:探索比特币DeFi生态中的PSBT
  • day38-SSH安全登录
  • Android Studio的笔记--BusyBox相关
  • Javascript面试手撕常见题目(回顾一)
  • 前端利用JS实现自定义表格滚动效果
  • 【C++】角谷猜想问题分析与解答
  • 基于Java Web的“使用Ajax实现无刷新实时显示公告信息”实验
  • Spring实例化的基本流程和Bean处理器
  • LeetCode 2545.根据第 K 场考试的分数排序:考察编程语言的排序
  • 现代 CSS 布局与响应式设计实战指南
  • asp.net多媒体教室管理系统VS开发sqlserver数据库web结构c#编程计算机网页项目
  • 使用Mac自带共享实现远程操作
  • TANGO与LabVIEW控制系统集成
  • [ESP]从零开始的Arduino IDE安装与ESP环境配置教程
  • HBase、Hive、Redis 和 MongoDB的对比
  • C语言的函数指针
  • linux-----文件命令
  • Latex 转换为 Word(使用GrindEQ )(英文转中文,毕业论文)
  • AdminJS - 集成 MySQL 的现代化管理面板开发指南
  • CSS3 实现火焰-小火苗效果
  • linux中大内核锁、互斥锁、信号量、完成变量、自旋锁区别
  • 【AIGC-ChatGPT进阶提示词-《动图生成》】怪物工厂:融合想象力与创造力的奇幻世界
  • vscode 使用说明
  • 四川托普信息技术职业学院教案1