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