likes
comments
collection
share

Drag and Drop(html5的优良特性)

作者站长头像
站长
· 阅读数 26

前言

HTML5 的拖拽(Drag and Drop)API 是一项在 Web 开发中非常有用的特性,它允许用户通过拖拽元素来实现数据的传输和操作。通过拖拽,可以实现更丰富的交互效果,提升用户体验。

拖拽 API 的详细事件流程

  • dragstart: 当拖动操作开始时触发。可以在这个事件中设置拖动数据,改变拖动元素的外观等。

  • drag: 拖动过程中持续触发。通常用于监控拖动位置和状态。

  • dragover: 拖动元素在目标元素上方时持续触发。需要调用 event.preventDefault() 以允许放置操作。

  • dragenter: 拖动元素进入目标元素时触发。可以用于高亮显示目标元素。

  • dragleave: 拖动元素离开目标元素时触发。用于移除高亮显示。

  • drop: 拖动元素在目标元素上释放时触发。用于处理放置逻辑,如移动数据。

  • dragend: 拖动操作结束时触发。可以在此恢复元素外观等。

实现原理

  1. 拖动开始:当用户开始拖动一个可拖动元素时,会触发 dragstart 事件,开发者可以在该事件中设置被拖动的数据。

  2. 拖动过程:在拖动过程中,会不断触发 dragover 、dragenter 和 dragleave 事件,开发者可以在这些事件中实现拖放区域的样式变化或其他逻辑。

  3. 放置目标:当被拖动的元素被放置在拖放区域内时,会触发 drop 事件,开发者可以在该事件中处理拖放操作,如处理被拖动的数据。

代码示例

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Drag and Drop Example</title>
  <style>
    * {
      box-sizing: border-box;
    }

    body {
      background-color: #1a89c1;
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100vh;
      overflow: hidden;
      margin: 0;
    }

    .empty {
      height: 150px;
      width: 150px;
      margin: 10px;
      border: 3px solid #000;
      background: #faf9f9;
    }

    .fill {
      width: 145px;
      height: 145px;
      cursor: pointer;
      background-image: url("../music/assets/bg.jpg");
      background-size: cover;
    }

    .hold {
      border: 5px solid #ccc;
    }

    .hovered {
      background: #333;
      border-color: white;
      border-style: dashed;
    }
  </style>
</head>
<body>
  <div class="empty">
    <div class="fill" draggable="true">

    </div>
  </div>
  <div class="empty"></div>
  <div class="empty"></div>
  <div class="empty"></div>
  <div class="empty"></div>

  <script>
    // 获取填充元素和空白区域的引用
    const fill = document.querySelector('.fill');
    const empties = document.querySelectorAll('.empty');

    // 添加填充元素的拖拽事件监听器
    fill.addEventListener('dragstart', dragStart);
    fill.addEventListener('dragend', dragEnd);

    // 添加空白区域的拖放事件监听器
    for (let empty of empties) {
      empty.addEventListener('dragover', dragOver);
      empty.addEventListener('dragenter', dragEnter);
      empty.addEventListener('dragleave', dragLeave);
      empty.addEventListener('drop', dragDrop);
    }

    // 拖拽开始时触发的函数
    function dragStart() {
      console.log('dragstart');
      // 添加 CSS 类来标识当前元素正在被拖拽
      this.classList.add('hold');
    }

    // 拖拽结束时触发的函数
    function dragEnd() {
      console.log('dragend');
      // 移除 CSS 类
      this.classList.remove('hold');
    }

    // 在空白区域上拖拽时触发的函数
    function dragOver(e) {
      // 阻止默认行为,以允许元素在此处被放置
      e.preventDefault();
      console.log('dragover');
    }

    // 拖拽进入空白区域时触发的函数
    function dragEnter(e) {
      e.preventDefault();
      // 添加 CSS 类以表示拖拽元素进入了空白区域
      this.classList.add('hovered');
      console.log('dragenter');
    }

    // 拖拽离开空白区域时触发的函数
    function dragLeave() {
      // 移除 CSS 类
      this.classList.remove('hovered');
      console.log('dragleave');
    }

    // 在空白区域上释放拖拽元素时触发的函数
    function dragDrop() {
      // 清除之前可能存在的类名,以便放置新的元素
      this.className = 'empty';
      // 将填充元素放置到空白区域中
      this.append(fill);
      console.log('dragdrop');
    }
  </script>
</body>
</html>

实现效果:

Drag and Drop(html5的优良特性)

拖拽 API 的高级用法

1. 设置拖动数据

dragstart 事件中,可以使用 event.dataTransfer 来设置拖动的数据。

function dragStart(event) {
  event.dataTransfer.setData('text/plain', 'This text may be dragged');
}

2. 自定义拖动图像

可以使用 event.dataTransfer.setDragImage 来自定义拖动过程中显示的图像。

function dragStart(event) {
  const img = new Image();
  img.src = 'path/to/image.png';
  event.dataTransfer.setDragImage(img, 10, 10);
}

3. 拖动多个元素

通过设置一个容器中的多个元素的 draggable 属性为 true,并为每个元素添加 dragstart 事件监听器,可以实现同时拖动多个元素。在 dragStartMultiple 函数中,将多个被选中元素的 HTML 内容拼接成一个字符串,并将其设置为拖动数据。

const selectedItems = document.querySelectorAll('.selected');
selectedItems.forEach(item => {
  item.draggable = true;
  item.addEventListener('dragstart', dragStartMultiple);
});

function dragStartMultiple(event) {
  const draggedItems = Array.from(selectedItems).map(item => item.outerHTML).join('');
  event.dataTransfer.setData('text/html', draggedItems);
}

4. 拖动文件

使用 dragover 和 drop 事件可以处理文件的拖放操作。在这个例子中,通过阻止默认行为并添加和移除类名来改变拖放区域的样式,同时处理 drop 事件来获取拖放的文件并进行相应的处理。

const dropZone = document.querySelector('.drop-zone');

dropZone.addEventListener('dragover', event => {
  event.preventDefault();
  dropZone.classList.add('drag-over');
});

dropZone.addEventListener('dragleave', () => {
  dropZone.classList.remove('drag-over');
});

dropZone.addEventListener('drop', event => {
  event.preventDefault();
  const files = event.dataTransfer.files;
  handleFiles(files);
});

最后

学会拖拽的小伙伴,麻烦点个赞吧!

转载自:https://juejin.cn/post/7376491813169578021
评论
请登录