joken-前端工程师

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::
  404 随笔 :: 39 文章 :: 8 评论 :: 20万 阅读

结论: 要实现一个元素可以拖动,并在拖动时生成一个拷贝的元素跟随鼠标移动,可以通过 JavaScript 的 dragdragstart 事件结合 CSS 样式来完成。


详细展开

1. HTML 结构

创建一个可拖动的元素,设置其 draggable="true" 属性。

<div id="draggable" draggable="true" style="width: 100px; height: 100px; background: lightblue;">
  拖动我
</div>

2. CSS 样式

为拖动时生成的拷贝元素设置样式(如透明度、大小等),以增强视觉效果。

/* 设置拖动时的样式 */
.dragging {
  opacity: 0.5; /* 设置透明度 */
  position: fixed; /* 固定位置,跟随鼠标 */
  pointer-events: none; /* 防止鼠标交互影响 */
}

3. JavaScript 实现

使用 dragstartdrag 事件监听器来控制拖动行为,并动态创建和更新拷贝元素的位置。

const draggable = document.getElementById('draggable');

// 监听 dragstart 事件,初始化拖动
draggable.addEventListener('dragstart', (event) => {
  // 创建一个拷贝元素
  const copyElement = draggable.cloneNode(true);
  copyElement.classList.add('dragging');
  document.body.appendChild(copyElement);

  // 将拷贝元素存储到 dataTransfer 中
  event.dataTransfer.setData('text/plain', '拖动的内容');
  event.dataTransfer.setDragImage(copyElement, 0, 0); // 设置拖动时的图像

  // 保存拷贝元素的引用
  event.dataTransfer.setData('copyElementId', copyElement.id);
});

// 监听 drag 事件,更新拷贝元素的位置
document.addEventListener('drag', (event) => {
  const copyElementId = event.dataTransfer.getData('copyElementId');
  const copyElement = document.querySelector(`[id="${copyElementId}"]`);

  if (copyElement) {
    // 更新拷贝元素的位置
    copyElement.style.left = `${event.pageX}px`;
    copyElement.style.top = `${event.pageY}px`;
  }
});

// 监听 dragend 事件,清理拷贝元素
draggable.addEventListener('dragend', () => {
  const copyElement = document.querySelector('.dragging');
  if (copyElement) {
    copyElement.remove(); // 移除拷贝元素
  }
});

关键点解析

  1. draggable="true"

    • 设置元素为可拖动状态。
  2. dragstart 事件:

    • 在拖动开始时触发。
    • 使用 event.dataTransfer.setDragImage 设置拖动时的图像(可以是拷贝元素本身)。
  3. drag 事件:

    • 在拖动过程中持续触发。
    • 更新拷贝元素的位置,使其跟随鼠标移动。
  4. dragend 事件:

    • 在拖动结束时触发。
    • 清理生成的拷贝元素,避免残留。

完整示例

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>拖动拷贝示例</title>
  <style>
    #draggable {
      width: 100px;
      height: 100px;
      background: lightblue;
      text-align: center;
      line-height: 100px;
      cursor: grab;
    }

    .dragging {
      opacity: 0.5;
      position: fixed;
      pointer-events: none;
    }
  </style>
</head>
<body>
  <div id="draggable" draggable="true">拖动我</div>

  <script>
    const draggable = document.getElementById('draggable');

    draggable.addEventListener('dragstart', (event) => {
      const copyElement = draggable.cloneNode(true);
      copyElement.classList.add('dragging');
      document.body.appendChild(copyElement);

      event.dataTransfer.setData('text/plain', '拖动的内容');
      event.dataTransfer.setDragImage(copyElement, 0, 0);

      event.dataTransfer.setData('copyElementId', copyElement.id);
    });

    document.addEventListener('drag', (event) => {
      const copyElementId = event.dataTransfer.getData('copyElementId');
      const copyElement = document.querySelector(`[id="${copyElementId}"]`);

      if (copyElement) {
        copyElement.style.left = `${event.pageX}px`;
        copyElement.style.top = `${event.pageY}px`;
      }
    });

    draggable.addEventListener('dragend', () => {
      const copyElement = document.querySelector('.dragging');
      if (copyElement) {
        copyElement.remove();
      }
    });
  </script>
</body>
</html>

总结

通过上述方法,可以轻松实现一个元素拖动时生成拷贝并跟随鼠标移动的效果。关键在于正确使用 dragstartdragdragend 事件,以及动态创建和更新拷贝元素的位置。

posted on   joken1310  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示