Drag(拖拽)是一个在计算机操作中非常常见的交互动作,它允许用户通过鼠标、触摸屏或其他输入设备选择并移动对象。以下是对拖拽动作的详细解释:### 定义拖拽(Drag)是指用户在界面上选择一个对象(如文件、图片、图标等),然后通过移动输入设备(如鼠标或触摸
摘要:拖放功能,即将一个元素从一个区域,通过拖拽,放置到另一个区域。常见的应用是将文件或图片从一个区域,拖放到另一个区域。中文常常把这表述成拖拽,实际上拖拽的描述并不准确,应该叫拖放,因为drag事件和drop事件是成对使用的,即拖拽和放置。 d
拖放功能,即将一个元素从一个区域,通过拖拽,放置到另一个区域。常见的应用是将文件或图片从一个区域,拖放到另一个区域。中文常常把这表述成拖拽,实际上拖拽的描述并不准确,应该叫拖放,因为drag事件和drop事件是成对使用的,即拖拽和放置。
drag在拖拽动作发生时触发,携带被拖拽元素的信息,drop在放置元素时触发,接收传递的拖拽元素的信息。
由于常常表述成拖拽,所以有些人在实现拖动功能时以为会触发drag事件,比如侧边栏拖拽。实际上drag是为拖放功能设计的(要配合drop),拖动(or拖拽)的功能应该用mousemove事件去实现,用错事件就会觉得怎么拖拽功能好难啊。
P.S.
drag和mousemove事件都是在移动鼠标的过程中触发,所以两个事件是会冲突的,如果发现其中一个事件不生效,可以检查下是不是因为有元素绑定了其中一个事件,导致另一个事件没有trigger。
具体实现
拖放,拖拽和放置,那么自然需要一个拖拽的区域,和一个放置的区域。
首先,要定义允许拖拽的元素。浏览器的默认行为是,文本、图像和链接是允许拖拽的。即<p>、<img>、<a>标签是默认允许拖拽的,其他元素要允许拖拽,则要设置draggle="true"。这个属性不允许简写。<div draggable ></div>并不会生效。
其次,要定义拖拽的数据。比如,拖拽的是文本,则设置成文本格式,并设置拖拽的数据内容。拖拽的是图片,则设置成图片格式,设置数据内容。定义成图片格式,那么拖拽的时候,鼠标旁边就会显示一张设置的图片。设置的拖拽数据可以有多个。
先给拖拽的元素绑定dragstart事件,再设置dataTransfer。示例代码如下:
function dragstart_handler(ev) {
// 添加拖拽数据
ev.dataTransfer.setData("text/plain", ev.target.innerText);
ev.dataTransfer.setData("text/html", ev.target.outerHTML);
ev.dataTransfer.setData(
"text/uri-list",
ev.target.ownerDocument.location.href,
);
}
拖放相关的事件对象event中,有一个dataTranster属性,这个属性保存着拖放过程中的数据。并有一些属性和方法设置和操作这些数据。
比较常用到的属性和方法有:
dropEffect:设置放置操作的类型,可以修改放置时鼠标的显示。比如设置成none,鼠标就会显示成禁止的样式。
effectAllowed:设置拖放过程的操作类型,同样影响鼠标的显示。
setData():设置拖放的数据。一般会在dragstart事件中用到。一个事件中,setData可以设置多个数据。但同类型的数据只能添加一项,重复添加会被最后添加的覆盖。
getData():检索获取拖放的数据。一般会在drop事件中用到。
具体可以参考MDN文档。
最后,就是在drop区域中放置拖拽的元素。
一个代码示例:
function drop_handler(ev) {
const data = ev.dataTransfer.getData("text/plain");
ev.target.textContent = data;
}
这样,拖放就结束了。拖放功能也完成了。
在拖放过程中,有一些全局事件触发,可以参考下表,具体请查看MDN文档。
事件
触发时刻
drag
当拖拽元素或选中的文本时触发。
dragend
当拖拽操作结束时触发 (比如松开鼠标按键或敲“Esc”键).
dragenter
当拖拽元素或选中的文本刚进入到一个可释放目标时触发。
dragleave
当拖拽元素或选中的文本离开一个可释放目标时触发。
dragover
当元素或选中的文本被拖到一个可释放目标上时触发(每 100 毫秒触发一次)。
dragstart
当用户开始拖拽一个元素或选中的文本时触发。
drop
当元素或选中的文本在可释放目标上被释放时触发。
一些问题
但是,这样实现拖放功能会有一些体验问题,鼠标的样式显示可能不正确。
以下是一些可能的问题:
1.禁止放置的区域没有显示禁止图标。
