Html 简明教程

HTML - Drag and Drop API

Drag and Drop (DnD) 是一个功能强大的用户界面概念,它可以借助鼠标点击和移动轻松地复制、重新排列和删除项目。这允许用户点击并按住鼠标按钮放置在某个元素上,将其拖动到另一个位置,然后释放鼠标按钮以将元素放置在那里。

要使用传统的 HTML4 实现拖放功能,开发人员必须使用复杂的 JavaScript 编程或其他 JavaScript 框架(如 jQuery 等)。

现在,HTML5 使用拖放 (DnD) API,为浏览器提供原生 DnD 支持,从而更容易进行编码。它受到 Chrome、Firefox 3.5 和 Safari 4 等所有主流浏览器的支持。

Making an Element Draggable

要让元素可拖动,我们必须将 draggable 属性设置为真。例如,

<div draggable="true">

Drag and Drop Events

在拖放操作的不同阶段会触发许多事件。下面列出了这些事件:

Events

Description

dragstart

当用户开始拖动对象时触发。

dragenter

当鼠标在拖动期间首次移动到目标元素上时触发。此事件的侦听器应指示是否允许将对象放置在此位置。如果没有侦听器,或侦听器不执行任何操作,则默认情况下不允许放置。

dragover

当鼠标在进行拖动时移动到元素上方时触发此事件。在侦听器中执行的操作在很多情况下都与 dragenter 事件相同。

dragleave

当鼠标在进行拖动时离开元素时触发此事件。侦听器应删除任何用于删除反馈的高亮或插入标记。

drag

鼠标在对象被拖动时每次移动都会触发。

drag

drop 事件会在拖动操作结束时触发,在下降区域的元素上触发。监听器负责检索被拖动的对象并将它放置在下降区域。

dragend

用户在拖动对象时松开鼠标按钮时触发。

Note 只触发了拖动事件;鼠标事件如 mousemove 在拖动操作期间并未触发。

The DataTransfer Object

所有拖放事件的事件监听器方法都接受 Event 对象,它有一个只读属性,称为 dataTransfer

event.dataTransfer 返回与以下事件关联的 DataTransfer 对象。

function EnterHandler(event) {
   DataTransfer dt = event.dataTransfer;
   .............
}

DataTransfer 对象保存有关拖放操作的数据。这些数据可以根据与 DataTransfer 对象关联的各种属性进行检索和设置,如下所示:

Attribute

Description

dataTransfer.dropEffect [ = value ]

返回当前选择的操作类型。此属性可以设置,以更改选定的操作。可能的值包括 none、copy、link 和 move。

dataTransfer.effectAllowed [ = value ]

返回允许的操作类型。此属性可以设置,以更改允许的操作。可能的值包括 none、copy、copyLink、copyMove、link、linkMove、move、all 和 uninitialized。

dataTransfer.types

返回一个 DOMStringList,其中列出了在 dragstart 事件中设置的格式。此外,如果拖动的是文件,则其中一种类型将为字符串“Files”。

dataTransfer.clearData ( [ format ] )

移除指定格式的数据。如果未提供参数,则移除所有数据。

dataTransfer.setData(format, data)

Adds the specified data.

data = dataTransfer.getData(format)

返回指定的数据。如果不存在这种数据,则返回空字符串。

dataTransfer.files

返回正在拖动的文件的 FileList(如果有)。

dataTransfer.setDragImage(element, x, y)

使用给定的元素来更新拖动反馈,替换任何先前指定的反馈。

dataTransfer.addElement(element)

将给定的元素添加到用于呈现拖动反馈的元素列表中。

Drag and Drop Process

以下是要执行以实现拖放操作的步骤:

Step 1 - Making an Object Draggable

以下步骤需采取:

  1. 如果需要拖拽一个元素,你需要为该元素将 draggable 特性设置为 true

  2. dragstart 设置一个监听事件,该事件存储被拖拽的数据。

  3. 监听事件 dragstart 将设置允许的效果(复制、移动、链接或它们的组合)。

以下是使一个对象可拖动的示例

<!DOCTYPE html>
<html>
<head>
   <style type="text/css">
      #boxA,
      #boxB {
         float: left;
         padding: 10px;
         margin: 10px;
         -moz-user-select: none;
      }
      #boxA {
         background-color: #6633FF;
         width: 75px;
         height: 75px;
      }
      #boxB {
         background-color: #FF6699;
         width: 150px;
         height: 150px;
      }
   </style>
   <script type="text/javascript">
      function dragStart(ev) {
         ev.dataTransfer.effectAllowed = 'move';
         ev.dataTransfer.setData("Text",
                        ev.target.getAttribute('id'));
         ev.dataTransfer.setDragImage(ev.target, 0, 0);
         return true;
      }
   </script>
</head>
<body>
   <center>
      <h2>Drag and drop HTML5 demo</h2>
      <div>
         Try to drag the purple box around.
      </div>
      <div id="boxA"
           draggable="true"
           ondragstart="return dragStart(event)">
               <p>Drag Me</p>
      </div>
      <div id="boxB">Dustbin</div>
   </center>
</body>
</html>

Step 2 - Handle dropping of the Object

为了接受一个拖放,拖放目标至少要监听三个事件。

  1. 第一个是 dragenter 事件,用于确定拖放目标是否会接受拖放。如果需要接受拖放,则此事件必须取消。

  2. 第二个是 dragover 事件,用于确定要向用户展示什么反馈。如果此事件被取消,那么反馈(通常是光标)将根据属性 dropEffect 的值进行更新。

  3. 最后,第三个是 drop 事件,它允许执行实际的拖放。

以下是将一个对象 drop 到另一个对象中的示例

<!DOCTYPE html>
<html>
<head>
   <style type="text/css">
      #boxA,
      #boxB {
         float: left;
         padding: 10px;
         margin: 10px;
         -moz-user-select: none;
      }

      #boxA {
         background-color: #6633FF;
         width: 75px;
         height: 75px;
      }

      #boxB {
         background-color: #FF6699;
         width: 150px;
         height: 150px;
      }
   </style>
   <script type="text/javascript">
      function dragStart(ev) {
         ev.dataTransfer.effectAllowed = 'move';
         ev.dataTransfer.setData("Text",
                        ev.target.getAttribute('id'));
         ev.dataTransfer.setDragImage(ev.target, 0, 0);
         return true;
      }

      function dragEnter(ev) {
         event.preventDefault();
         return true;
      }

      function dragOver(ev) {
         return false;
      }

      function dragDrop(ev) {
         var src = ev.dataTransfer.getData("Text");
         ev.target.appendChild(document.getElementById(src));
         ev.stopPropagation();
         return false;
      }
   </script>
</head>
<body>
   <center>
      <h2>Drag and drop HTML5 demo</h2>
      <div>
         Try to move the purple box into the pink box.
      </div>
      <div id="boxA"
           draggable="true"
           ondragstart="return dragStart(event)">
               <p>Drag Me</p>
      </div>
      <div id="boxB"
           ondragenter="return dragEnter(event)"
           ondrop="return dragDrop(event)"
           ondragover="return dragOver(event)">
                  Dustbin
      </div>
   </center>
</body>
</html>