javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript原生拖放

JavaScript原生拖放详解

作者:橘猫吃不胖~

本文介绍了HTML5拖放事件的处理方法,包括拖放事件的触发顺序、dataTransfer对象的使用以及可拖动能力的设置,通过这些方法,可以实现更丰富的用户交互效果

拖放事件

拖放事件可以让开发者控制拖放操作的方方面面,关键的部分是确定每个事件是在哪里触发的,有的事件在被拖放元素上触发,有的事件则在放置目标上触发。

当某个元素被拖动时,会按顺序触发以下事件:

事件说明
dragstart按住鼠标不放开始移动鼠标时触发
drag元素正在被拖动时触发
dragend停止拖动时触发

在把元素拖动到一个有效的放置目标上时,会依次触发以下事件:

事件说明
dragenter被拖动的元素进入目标容器时触发
dragover被拖拽元素在目标容器内拖动时触发
dragleave被拖动元素离开目标容器时触发
drop被拖动元素放到了目标容器上触发

如果我们想让一个元素可以被拖放,还要为该元素添加dragabble属性

dataTransfer对象

dataTransfer对象实现了拖动操作中的数据传输,用于从被拖动元素向放置目标传递字符串数据。

因为这个对象是event的属性,所以在拖放事件的事件处理程序外部无法访问dataTransfer

该对象内部有以下属性和方法:

事件说明
dropEffect可以告诉浏览器允许哪种放置行为,获取当前选定的拖放操作类型或者设置的为一个新的类型。值必须为none, copy, link、move。
effectAllowed表示对被拖动元素是否允许dropEffect,提供所有可用的操作类型。必须是none, copy, copyLink, copyMove, link, linkMove, move, all、uninitialized之一。
files包含数据传输中可用的所有本地文件的列表。如果拖动操作不涉及拖动文件,则此属性为空列表。
items提供一个包含所有拖动数据列表的DataTransferItemList对象。
types一个提供dragstart事件中设置的格式的strings数组。
clearData()删除与给定类型关联的数据。类型参数是可选的。如果类型为空或未指定,则删除与所有类型关联的数据。如果指定类型的数据不存在,或者data transfer中不包含任何数据,则该方法不会产生任何效果。
getData()检索给定类型的数据,如果该类型的数据不存在或data transfer不包含数据,则返回空字符串。
setData()设置给定类型的数据。如果该类型的数据不存在,则将其添加到末尾,以便类型列表中的最后一项将是新的格式。如果该类型的数据已经存在,则在相同位置替换现有数据。
setDragImage()用于设置自定义的拖动图像。

可拖动能力

HTML5在所有HTML元素上规定了一个draggable属性,表示元素是否可以拖动。

图片和链接的draggable属性自动被设置为true,而其他所有元素此属性的默认值为false

如果想让其他元素可拖动,或者不允许图片和链接被拖动,都可以设置这个属性。

示例代码:

<!-- 禁止拖动图片 -->
<img src="smile.gif" draggable="false" alt="Smiley face">
<!-- 让元素可以拖动 -->
<div draggable="true">...</div>

一个拖动demo

设置一个可以拖拽的元素:

<div id="draggable" draggable="true">Drag me!</div>
#draggable {
  width: 100px;
  height: 100px;
  background-color: #3498db;
  color: #fff;
  text-align: center;
  line-height: 100px;
  cursor: move;
  position: absolute;
}

const draggableElement = document.getElementById('draggable');
let offsetX, offsetY;
draggableElement.addEventListener('dragstart', function (event) {
  // 拖动开始时计算鼠标位置与元素左上角的偏移,并记录
  offsetX = event.clientX - draggableElement.getBoundingClientRect().left;
  offsetY = event.clientY - draggableElement.getBoundingClientRect().top;
});

draggableElement.addEventListener('drag', function (event) {
  // 计算元素应该移动到的位置
  const x = event.clientX - offsetX;
  const y = event.clientY - offsetY;
  // 更新元素位置
  draggableElement.style.left = x + 'px';
  draggableElement.style.top = y + 'px';
});

draggableElement.addEventListener('dragend', function (event) {
  const x = event.clientX - offsetX;
  const y = event.clientY - offsetY;
  // 拖动结束之后更新元素的位置
  draggableElement.style.left = x + 'px';
  draggableElement.style.top = y + 'px';
});

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文