拖放(DnD)是一個強大的用戶界面相關(guān)的概念,借助鼠標點擊的幫助,它讓復(fù)制,重新排序以及刪除條目變得很容易。這就允許用戶在某個元素上點擊并按住鼠標按鍵,把它拖到另外一個位置,然后釋放鼠標按鍵把與元素放到該位置。
要使用傳統(tǒng)的 HTML4 實現(xiàn)拖放的功能,開發(fā)者要么使用復(fù)雜的 JavaScript 變成,要么使用 JavaScript 框架,比如 jQuery 等等。
現(xiàn)在 HTML5 提出了拖放(DnD)API,為瀏覽器帶來了原生拖放支持,讓編碼變得更容易。
所有的主流瀏覽器比如 Chrome,F(xiàn)ireFox 3.5 以及 Safari 4 等等都支持 HTML5 拖放。
下面列出了一些在執(zhí)行拖放操作各個階段會觸發(fā)的事件:
| 事件 | 描述 |
|---|---|
| dragstart | 用戶開始拖動對象時觸發(fā)。 |
| dragenter | 鼠標初次移到目標元素并且正在進行拖動時觸發(fā)。這個事件的監(jiān)聽器應(yīng)該之指出這個位置是否允許放置元素。如果沒有監(jiān)聽器或者監(jiān)聽器不執(zhí)行任何操作,默認情況下不允許放置。 |
| dragover | 拖動時鼠標移到某個元素上的時候觸發(fā)。大多數(shù)時候,監(jiān)聽器觸發(fā)的操作與 dragenter 事件相同。 |
| dragleave | 拖動時鼠標離開某個元素的時候觸發(fā)。監(jiān)聽器應(yīng)該移除用于放置反饋的高粱或插入標記。 |
| drag | 對象被拖拽時每次鼠標移動都會觸發(fā)。 |
| drop | 拖動操作結(jié)束,放置元素時觸發(fā)。監(jiān)聽器負責檢索被拖動的數(shù)據(jù)以及在放置位置插入它。 |
| dragend | 拖動對象時用戶釋放鼠標按鍵的時候觸發(fā)。 |
注意:只會觸發(fā)拖動事件;拖動操作期間鼠標事件,比如 mousemove 并不會觸發(fā)。
所有 drag 和 drop 事件的事件監(jiān)聽器都接收一個 Event 對象作為參數(shù),它有一個叫做 dataTransfer 的只讀屬性。event.dataTransfer 返回與事件相關(guān)的 DataTransfer 對象,如下所示:
function EnterHandler(event) {
DataTransfer dt = event.dataTransfer;
.............
}
DataTransfer 對象持有 drag 和 drop 操作相關(guān)的數(shù)據(jù)??梢詸z索這些數(shù)據(jù)以及設(shè)置 DataTransfer 對象相關(guān)聯(lián)的各種屬性,正如下面所闡述的:
| S.N. | DataTransfer 屬性及其描述 |
|---|---|
| 1 |
dataTransfer.dropEffect [ = value ]
|
| 2 |
dataTransfer.effectAllowed [ = value ]
|
| 3 |
dataTransfer.types
返回列出設(shè)置給 dragstart 事件格式的 DOMStringList。此外,如果任意文件被拖拽,那么其中一個類型將會是字符串“Files"。 |
| 4 |
dataTransfer.clearData( [ format ] )
移除指定格式的數(shù)據(jù)。如果省略參數(shù)則移除所有數(shù)據(jù)。 |
| 5 |
dataTransfer.setData(format, data)
添加給定的數(shù)據(jù)。 |
| 6 |
data = dataTransfer.getData(format)
返回指定的數(shù)據(jù)。如果沒有該數(shù)據(jù)則返回空字符串。 |
| 7 |
dataTransfer.files
如果有,返回表示被拖拽文件的 FileList。 |
| 8 |
dataTransfer.setDragImage(element, x, y)
使用給定的元素更新拖拽反饋信息,替換先前指定的反饋信息。 |
| 9 |
dataTransfer.addElement(element)
把給定的元素添加到用來渲染拖拽反饋的元素列表。 |
下面是實現(xiàn)拖拽操作的步驟:
下面是要采用的步驟:
下面是一個讓對象可拖拽的示例:
<!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>
便于學習上述概念 - 請使用最新版的 FireFox,Safari 或 Chrome 進行在線練習。
為了接受放置,放置目標至少要監(jiān)聽三個事件。
下面是把一個對象放入另一個對象的示例:
<!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>
便于學習上述概念 - 請使用最新版的 FireFox,Safari 或 Chrome 進行在線練習。