HTML5 在 IE 的拖放实现基础上标准化了拖放功能。所有主流浏览器都根据 HTML5 规范 实现了原生的拖放。

关于拖放最有意思的可能就是可以跨窗格、跨浏览器容器,有时候甚至可以跨应用程序拖动元素。

浏览器对拖放的支持可以让我们实现这些功能。

拖放事件

有的事件在被拖放元素上触发,有的事件则在放置目标上触发。

被拖动元素

大多数浏览器此时会创建元素的一个半透明副本,始终 跟随在光标下方

在某个元素被拖动时,会(按顺序) 触发以下事件:
(1) dragstart:在按住鼠标键不放并开始移动鼠标的那一刻,此时光标会 变成非放置符号(圆环中间一条斜杠),表示元素不能放到自身上。
(2) drag:只要目标还被拖动就会持续触发 drag 事件,随着鼠标移动而不断触发。
(3) dragend:当拖动停止时(把元素放到有效或无效的放置目标上)

有效的放置目标

在把元素拖动到一个有效的放置目标上时,会依次触发以下事件:
(1) dragenter:只要一把元素拖动到放置目标上(类似于 mouseover 事件)
(2) dragover:元素在放置目标范围内被拖动期间此事件会持续触发
(3) dragleave 当元素被拖动到放置目标之外

(3) drop:被拖动元素被放到了目标上

这些事件的目 标是放置目标元素

自定义放置目标

在把某个元素拖动到无效放置目标上时,会看到一个特殊光标(圆环中间一条斜杠)表示不能放下。

即使所有元素都支持放置目标事件,这些元素默认也是不允许放置的。

如果把元素拖动到不允许放置的 目标上,无论用户动作是什么都不会触发 drop 事件。

不过,通过覆盖 dragenter 和 dragover 事件 的默认行为,可以把任何元素转换为有效的放置目标。

  1. // <div>元素,那么可以使用以下代码把它转换成一个放置目标
  2. let droptarget = document.getElementById("droptarget");
  3. droptarget.addEventListener("dragover", (event) => {
  4. event.preventDefault();
  5. });
  6. droptarget.addEventListener("dragenter", (event) => {
  7. event.preventDefault();
  8. });

执行上面的代码之后,把元素拖动到这个

上应该可以看到光标变成了允许放置的样子。另外, drop 事件也会触发。

可拖动能力

默认情况下,图片、链接和文本是可拖动的,这意味着无须额外代码用户便可以拖动它们。

文本只 有在被选中后才可以拖动,而图片和链接在任意时候都是可以拖动的。

我们也可以让其他元素变得可以拖动。

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

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

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

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