Skip to content

拖拽API drag

HTML5 拖放 API 允许开发人员创建交互式 Web 应用程序,使用户能够在网页内或不同窗口或应用程序之间拖放元素

关键概念

  • 可拖动元素: 通过将 draggable 属性设置为 true 来使元素可拖动。
  • 拖动事件: 当用户拖动元素时,事件主体是被拖放元素 ,允许您处理拖动操作的不同阶段:
    • dragstart: 在用户开始拖动元素时触发。
    • drag: 在用户拖动元素时持续触发。
    • dragend: 在用户释放元素时触发。
  • 放置目标: 事件主体是目标元素,可以接收拖放元素的元素称为放置目标。它们监听以下事件:
    • dragenter: 当可拖动元素进入放置目标时触发。
    • dragover: 当可拖动元素位于放置目标上方时持续触发。
    • dragleave: 当可拖动元素离开放置目标时触发。
    • drop: 当可拖动元素被放置在放置目标上时触发。
  • 数据传输 :DataTransfer 对象用于在可拖动元素和放置目标之间传输数据。可以使用 setData() 设置要传输的数据,并使用 getData() 检索数据。

基本用法

  1. 使元素可拖动:
html
<img src="image.jpg" draggable="true">
  1. 添加拖动事件的事件侦听器:
javascript
image.addEventListener('dragstart', handleDragStart);
image.addEventListener('dragend', handleDragEnd);
  1. 实现事件处理程序:
javascript
function handleDragStart(event) {
    // 设置要传输的数据
    event.dataTransfer.setData('text/plain', image.id);
}

function handleDragEnd(event) {
    // 处理拖动完成
}
  1. 使元素成为放置目标:
html
<div id="drop-target"></div>
  1. 添加放置事件的事件侦听器:
javascript
dropTarget.addEventListener('dragenter', handleDragEnter);
dropTarget.addEventListener('dragover', handleDragOver);
dropTarget.addEventListener('drop', handleDrop);
  1. 实现事件处理程序:
javascript
function handleDragEnter(event) {
    // 阻止默认行为以允许放置
    event.preventDefault();
}

function handleDragOver(event) {
    // 阻止默认行为以允许放置
    event.preventDefault();
}

function handleDrop(event) {
    // 获取传输数据
    const imageId = event.dataTransfer.getData('text/plain');
    // 使用已放置的数据执行某些操作
}

例子

两个格子之间图片可以相互拖拽

点击展开 例子代码
vue
<template>
  <div class="dragable">
    <div class="box drag box1">
      <img id="dragImg" src="/demo.jpg" draggable="true">
    </div>
    <div class="box drag box2">
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted } from 'vue';

onMounted(() => {
  const dragImg = document.querySelector('#dragImg');
  const box1 = document.querySelector('.drag.box1');
  const box2 = document.querySelector('.drag.box2');

  if (dragImg && box2 && box1) {
    // dragImg 监听dragstart
    dragImg.addEventListener('dragstart', (event) => {
      const dragEvent = event as DragEvent;
      dragEvent.dataTransfer?.setData('text/plain', dragImg.id);
    });
    // 阻止默认行为以允许放置
    box1.addEventListener('dragover', (event) => {
      event.preventDefault();
    });
    // 获取拖动的数据并将其放置到所选的放置目标中
    box1.addEventListener('drop', (event) => {
      event.preventDefault();
      const dragEvent = event as DragEvent;
      const data = dragEvent.dataTransfer?.getData('text/plain') as string;
      box1.appendChild(document.getElementById(data) as HTMLElement);
    });
    // 阻止默认行为以允许放置
    box2.addEventListener('dragover', (event) => {
      event.preventDefault();
    });
    // 获取拖动的数据并将其放置到所选的放置目标中
    box2.addEventListener('drop', (event) => {
      event.preventDefault();
      const dragEvent = event as DragEvent;
      const data = dragEvent.dataTransfer?.getData('text/plain') as string;
      box2.appendChild(document.getElementById(data) as HTMLElement);
    });

  }
})

</script>

<style lang="scss" scoped>
.dragable {
  display: flex;

  .box {
    width: 180px;
    height: 180px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-left: 12px;
  }

  .box1 {
    background-color: var(--jk-color-purple);
  }

  .box2 {
    background-color: var(--jk-color-blue);
  }
}
</style>