在实际应用中,当拖拽动作开始或者结束的时候会进行一些相应的后天操作,这时就需要使用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