在實際應用中,當拖拽動作開始或者結束的時候會進行一些相應的後天操作,這時就需要使用dojo的事件系統為拖拽事件添加事件處理函數。本文分別給出了基類dojo.dnd.DragSource和dojo.dnd.DropTarget的事件的用法,並附有原始碼。
第一部分:
為一個元素增加拖拽效果時,需要建立一個類的執行個體。dojo針對不同的拖拽功能實現了dojo.dnd.HtmlDragSource, dojo.dnd.HtmlDragCopySource和dojo.dnd.HtmlDragMoveSource三個類。這三個類具有共同的基類dojo.dnd.DragSource,該類定義了以下事件。
- onSelected:當被拖拽元素被選中時觸發,選中拖拽元素事件的處理函數
- onDragStart:當拖拽動作開始時觸發,拖拽開始事件的處理函數
- onDragEnd:當拖拽動作結束時觸發,拖拽結束事件的處理函數
註冊事件響應函數的方法是使用dojo的事件綁定機制(dojo.event.connect/kwConnect),下面通過一個簡單的執行個體示範如何添加拖拽事件的處理函數,樣本頁面的代碼如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset='UTF-8" />
<title>dojo.dnd 拖拽事件————onDragStart, onDragEnd, onSelected</title>
<script type="text/javascript">
var djConfig = {
isDebug: true
};
</script>
<script type="text/javascript" src="dojo-0.3.1-ajax/dojo.js">
</script>
<style type="text/css">
ul {
position: relative;
list-style: none;
margin: 0;
padding: 0;
overflow: visible;
}
li {
margin: 3px 0;
padding: 3px 3em 3px 10px;
border: 2px solid #456;
background-color: #cde;
cursor: move;
}
</style>
<script type="text/javascript">
dojo.require("dojo.dnd.HtmlDragMove");
dojo.require("dojo.event.*");
function init(){
//建立一個dojo.HtmlDragSource類的執行個體,使div元素具有被拖拽的功能
var drag = new dojo.dnd.HtmlDragSource(dojo.byId("div"));
//註冊拖拽結束事件的處理函數
dojo.event.connect(drag, "onDragEnd", function(evt){
//輸出調試資訊
dojo.debug("drag end");
});
//註冊拖拽開始事件的處理函數
dojo.event.connect(drag, "onDragStart", function(evt){
dojo.debug("drag start");
})
//註冊選中拖拽元素事件的處理函數
dojo.event.connect(drag, "onSelected", function(evt){
//alert("drag selected");
dojo.debug("drag selected");
});
}
//頁面載入時調用init()
dojo.event.connect(dojo, "loaded", "init");
function init11(){
//建立一個dojo.HtmlDragSource類的執行個體,使div元素具有被拖拽的功能
var drag11 = new dojo.dnd.HtmlDragSource(dojo.byId("list1"));
//註冊拖拽結束事件的處理函數
dojo.event.connect(drag11, "onDragEnd", function(evt){
//輸出調試資訊
dojo.debug("drag11 end");
});
//註冊拖拽開始事件的處理函數
dojo.event.connect(drag11, "onDragStart", function(evt){
dojo.debug("drag11 start");
})
//註冊選中拖拽元素事件的處理函數
dojo.event.connect(drag11, "onSelected", function(evt){
//alert("drag selected");
dojo.debug("drag11 selected");
});
}
//頁面載入時調用init11()
dojo.event.connect(dojo, "loaded", "init11");
</script>
</head>
<body>
<div id="div" style="width:200px;height:200px;background:blue">
onDragStart, onDragEnd, onSelected 的使用方法
</div>
<ul id="list1">
<li id="drag11">
列表1,條目1
</li>
<li id="drag12">
列表1,條目2
</li>
<li id="drag13">
列表1,條目3
</li>
</ul>
</body>
</html>
上述的樣本的頁面運行效果可以是:在被拖拽元素div或者list1的下方輸出調試資訊,該資訊反映了這個過程中三個事件被觸發的先後過程。
實現了整體拖拽,那麼清單項目的每一項都可以被拖拽嗎,並且同時執行以上三個事件?答案是肯定的,只須修改function函數。function函數的寫法應該結合前面第四節給出的可拖拽代碼進行修改。代碼修改為:
function init11(){
//使列表對象list1能夠接受被拖拽元素,被拖拽元素的類型是"li1"
var list1 = document.getElementById("list1");
new dojo.dnd.HtmlDropTarget(list1, ["li1"]);
//使list1中的每一個清單項目元素能夠被拖拽,其類型是“li1” ;同時具有複製拖拽的功能
var lis = list1.getElementsByTagName("li");
for (var x = 0; x < lis.length; x++) {
//建立一個dojo.HtmlDragSource類的執行個體,使div元素具有被拖拽的功能
var drag11=new dojo.dnd.HtmlDragSource(lis[x], "li1", false);
}
//註冊拖拽結束事件的處理函數
dojo.event.connect(drag11, "onDragEnd", function(evt){
//輸出調試資訊
dojo.debug("drag11 end");
});
//註冊拖拽開始事件的處理函數
dojo.event.connect(drag11, "onDragStart", function(evt){
dojo.debug("drag11 start");
})
//註冊選中拖拽元素事件的處理函數
dojo.event.connect(drag11, "onSelected", function(evt){
dojo.debug("drag11 selected");
});
}
上述的樣本的頁面運行效果可以是:在被拖拽元素list1或者list2的下方輸出調試資訊,該資訊反映了這個過程中三個事件被觸發的先後過程。
第二部分:
在拖拽元素的過程中,我們需要關注的不僅僅是被拖拽的元素,接受拖拽元素的容器也是同等重要的。與接受拖拽元素容器相關的類是dojo.dnd.HtmlDropTarget,它的基類是dojo.dnd.DropTarget。在dojo.dnd.DropTarget類中定義了以下事件:
- onDragOver: 元素被拖拽到容器上方時觸發
- onDragOut: 元素被拖拽出容器地區時觸發
- onDragMove: 元素在容器內部被拖拽時時觸發
- onDropStart/onDrop/onDropEnd: 元素在容器內部被拖拽時觸發
下面通過一個樣本來示範接受拖拽元素容器的事件處理,相關代碼如下:
<script type="text/javascript">
dojo.require("dojo.dnd.HtmlDragCopy");
dojo.require("dojo.event.*");
function init11(){
//使列表對象list1能夠接受被拖拽元素,被拖拽元素的類型是"li1"
var list1 = document.getElementById("list1");
var drop1=new dojo.dnd.HtmlDropTarget(list1, ["li1"]);
//使list1中的每一個清單項目元素能夠被拖拽,其類型是“li1” ;同時具有複製拖拽的功能
var lis = list1.getElementsByTagName("li");
for (var x = 0; x < lis.length; x++) {
//建立一個dojo.HtmlDragSource類的執行個體,使div元素具有被拖拽的功能
new dojo.dnd.HtmlDragCopySource(lis[x], "li1", false);
}
//使列表對象list2能夠接受被拖拽元素,被拖拽元素的類型是"li1"
var list2 = document.getElementById("list2");
var drop2=new dojo.dnd.HtmlDropTarget(list2, ["li1"]);
//使list2中的每一個清單項目元素能夠被拖拽,其類型是“li1” ;同時具有複製拖拽的功能
var lis = list2.getElementsByTagName("li");
for (var x = 0; x < lis.length; x++) {
new dojo.dnd.HtmlDragCopySource(lis[x], "li1", false);
}
//註冊drop1 的onDragOver事件的處理函數
dojo.event.connect(drop1, "onDragOver", function(evt){
//輸出調試資訊
dojo.debug("drop1 onDragOver");
});
//註冊drop1 的 onDragOut 事件的處理函數
dojo.event.connect(drop1, "onDragOut", function(evt){
dojo.debug("drop1 onDragOut");
})
//註冊drop1 的 onDragMove 事件的處理函數
dojo.event.connect(drop1, "onDragMove", function(evt){
dojo.debug("drop1 onDragMove");
});
//註冊drop1 的 onDropStart 事件的處理函數
dojo.event.connect(drop1, "onDropStart", function(evt){
dojo.debug("drop1 onDropStart");
});
//註冊drop1 的 onDrop 事件的處理函數
dojo.event.connect(drop1, "onDrop", function(evt){
dojo.debug("drop1 onDrop");
});
//註冊drop1 的 onDropEnd 事件的處理函數
dojo.event.connect(drop1, "onDropEnd", function(evt){
dojo.debug("drop1 onDropEnd");
});
//註冊drop2 的onDragOver事件的處理函數
dojo.event.connect(drop2, "onDragOver", function(evt){
//輸出調試資訊
dojo.debug("drop2 onDragOver");
});
//註冊drop2 的 onDragOut 事件的處理函數
dojo.event.connect(drop2, "onDragOut", function(evt){
dojo.debug("drop2 onDragOut");
})
//註冊drop2 的 onDragMove 事件的處理函數
dojo.event.connect(drop2, "onDragMove", function(evt){
dojo.debug("drop2 onDragMove");
});
//註冊drop2 的 onDropStart 事件的處理函數
dojo.event.connect(drop2, "onDropStart", function(evt){
dojo.debug("drop2 onDropStart");
});
//註冊drop2 的 onDrop 事件的處理函數
dojo.event.connect(drop2, "onDrop", function(evt){
dojo.debug("drop2 onDrop");
});
//註冊drop2 的 onDropEnd 事件的處理函數
dojo.event.connect(drop2, "onDropEnd", function(evt){
dojo.debug("drop2 onDropEnd");
});
}
<ul id="list1">
<li id="drag11">
列表1,條目1
</li>
<li id="drag12">
列表1,條目2
</li>
<li id="drag13">
列表1,條目3
</li>
</ul>
<hr/>
<ul id="list2">
<li id="drag21">
列表2,條目1
</li>
<li id="drag22">
列表2,條目2
</li>
<li id="drag23">
列表2,條目3
</li>
</ul>
上述的樣本的頁面運行效果可以是:一個清單項目從list1被拖拽到list2的過程,在下方輸出調試資訊,該資訊反映了這個過程中事件被觸發的情況。
類似過程如下:
DEBUG: drop1 onDragOver
DEBUG: drop1 onDragMove
DEBUG: drop1 onDragOut
DEBUG: drop2 onDragMove
DEBUG: drop2 onDragMove
DEBUG: drop2 onDragMove
DEBUG: drop2 onDragMove
DEBUG: drop2 onDropStart
DEBUG: drop2 onDragOut
DEBUG: drop2 onDrop
DEBUG: drop2 onDropEnd