使用Asp.net2.0和Atlas实现拖放操作
四、声明拖放区
拖动HTML元素在页面上划来划去,当松开鼠标时,这些HTML元素就被拖到了鼠标所在的位置,这看起来非常过隐。为了使这个功能更有用,当松开鼠标时可以引发一个事件。此外,这个事件的引发应该依赖于HTML放下的位置。换句话说,应该为这些被拖动的HTML对象加入拖放区,可以使用同样的方法将一个HTML div标签变成一个拖动对象。
在下面的例子中,我将展示如何使用Atlas来设置拖放区。默认情况下,Atlas并不支持使用和建立可拖动元素一样的方法来建立拖放区。要想实现这一功能,必须同时使用DrapDropList和DraggableListItem对象,你可以通过它们建立一个排序的拖放列表。如果你想了解更多的信息,可以在网上找到更多的使用DrapDropList的例子。
拖放区的主要缺点是只能对DragDropList中的元素起作用。因此,使用DrapDropList和DraggableListItem元素只能对特定的元素有效。为了实现上述的更为通用的拖放区功能,你需要自己使用JavaScript实现自己的拖放区类。幸运的是,实现这些并不困难。
为了拥有更强大的功能,Atlas为JavaScript增加了一些面向对象扩展,如命名空间、抽象类、接口等。你可以充分利用这些扩展来实现自定义拖放区。如果你看一看AtlasUIDrapDrop.js的源码(可以通过Visual Studio debugger查看源码),你就会发现在这个文件中定义了一些接口,这其中包括一个为Sys.UI.DrapSource定义的接口和一个为Sys.UI.DropTarget定义的接口。事实上,FloatingBehavior和DraggableListItem类实现了Sys.UI.DragSource接口,同时,Sys.UI.DropTarget实现了DrapDropList类。以下是这两个接口的代码:
Sys.UI.IDragSource = function() ...{
this.get_dataType = Function.abstractMethod;
this.get_data = Function.abstractMethod;
this.get_dragMode = Function.abstractMethod;
this.onDragStart = Function.abstractMethod;
this.onDrag = Function.abstractMethod;
this.onDragEnd = Function.abstractMethod;
}
Sys.UI.IDragSource.registerInterface('Sys.UI.IDragSource');
Sys.UI.IDropTarget = function() ...{
this.get_dropTargetElement = Function.abstractMethod;
this.canDrop = Function.abstractMethod;
this.drop = Function.abstractMethod;
this.onDragEnterTarget = Function.abstractMethod;
this.onDragLeaveTarget = Function.abstractMethod;
this.onDragInTarget = Function.abstractMethod;
}
Sys.UI.IDropTarget.registerInterface('Sys.UI.IDropTarget');
你为什么需要实现这些接口,而不是直接编写支持拖放或拖放区功能的类呢?原因是在幕后有一个叫DrapDropManager的类,这个类用于管理拖放操作中的被拖放的元素和拖放区之间的交互,而这个类仅仅能管理实现了IDragSource和IDropTarget接口的类。这个DragDropManager类的register可以使拖放区对每一个拖到这上面的对象进行限制,这一切是通过处理MouseOver事件完成的,通过MouseOver事件,拖动区可以只让一个对象拖到它的上面,而让其它的对象无法办到这一点。这个类完成了大多数的工作,因此,我们无需写更多的代码。首先,建立一个叫DropZoneBehavior.js的JavaScript文件。将它放在scriptLibrary目录中,但实现拖放区功能并不一定要这样做。接下来,将如下代码复制到这个文件中:
Type.registerNamespace('Custom.UI');
![]()
Custom.UI.DropZoneBehavior = function() ...{
![]()
Custom.UI.DropZoneBehavior.initializeBase(this);
this.initialize = function() ...{
Custom.UI.DropZoneBehavior.callBaseMethod(this, 'initialize');
// Register ourselves as a drop target.
Sys.UI.DragDropManager.registerDropTarget(this);
}
this.dispose = function() ...{
Custom.UI.DropZoneBehavior.callBaseMethod(this, 'dispose');
}
this.getDescriptor = function() ...{
var td = Custom.UI.DropZoneBehavior.callBaseMethod(this, 'getDescriptor');
return td;
}
![]()
// IDropTarget members.
this.get_dropTargetElement = function() ...{
return this.control.element;
}
this.drop = function(dragMode, type, data) ...{
alert('dropped');
}
this.canDrop = function(dragMode, dataType) ...{
return true;
}
this.onDragEnterTarget = function(dragMode, type, data) ...{
}
this.onDragLeaveTarget = function(dragMode, type, data) ...{
}
this.onDragInTarget = function(dragMode, type, data) ...{
}
}
Custom.UI.DropZoneBehavior.registerClass('Custom.UI.DropZoneBehavior',
Sys.UI.Behavior, Sys.UI.IDragSource,
Sys.UI.IDropTarget, Sys.IDisposable);
Sys.TypeDescriptor.addType('script', 'DropZoneBehavior',
Custom.UI.DropZoneBehavior);
![]()
我需要解释一下这个类。首先需要注意的是倒数第二行的开头部分“Custom.UI.DropZoneBehavior.registerClass”。它的作用是使用Atlas注册上面定义的DropZoneBehavior类。registerClass方法的第一个参数是类名。第二个参数是基类。后面的其它参数是第一个参数所指向的类所实现的接口。最后一行使这个类在Atlas脚本中可以使用。现在回到第一行,“Type.registerNamespace”方法注册了自定义的命名空间。下一行使用了匿名方法形式定义了一个新的类。我不太熟悉这种JavaScript语法,但这种语法对编写面向对象的JavaScript是非常重要的。在这个匿名方法中,定义了类的Initialize、Dispose和getDescriptor方法,这些方法都是标准的方法,它们都非常简单。在这些方法中唯一要做的就是调用基类同名的方法(就是在倒数第二行所指定的这个基类的方法)。除了这些,你只要做一件事,就是在Initialize方法中使用Sys.UI.DrapDropManager注册拖放对象。
接下来,在这个类中实现了IDropTarget的方法。在这个例子中只实现了两个方法,“this.canDrop”和“this.drop”。“canDrop”方法只返回一个true。当然,可以在这个方法中写更多的代码来实现更有趣的效果,但在我们这个例子中只是想实现拖动一个div标签。“drop”方法的实现也很简单。当一个被拖动的对象被放在拖放区上时,弹出一个对话框,以表示这个事件被成功调用。
也许你应该建立一个新的aspx页来展示一下你的自定义拖放区。上面的例子代码足可以完成这个功能。在Atlas脚本管理器中,除了注册AtlasUIDrapDrop脚本外,还应该注册上面的DropZoneBehavior脚本:
<atlas:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>...
<atlas:ScriptReference ScriptName="AtlasUIDragDrop" />
<atlas:ScriptReference Path="scriptLibrary/DropZoneBehavior.js" />
</Scripts>
</atlas:ScriptManager>
接下来,你应该在HTML body中加一个新的div标签,以便使这个div可以被拖动。
<div style="background-color:Red;height:200px;width:200px;">
<div id="draggableDiv" style="height:100px;width:100px;background-color:Blue;">
<div id="handleBar" style="height:20px;width:auto;background-color:Green;">
</div>
</div>
</div>
![]()
<div id="dropZone" style="background-color:cornflowerblue;height:200px;width:200px;">
Drop Zone
</div>
最后,你需要加一个XML标记,以使div对象可以响应拖放区的事件。XML标记如下:
![]()
<script type="text/xml-script">...
<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
<components>
<control id="dropZone">
<behaviors>
<DropZoneBehavior/>
</behaviors>
</control>
<control id="draggableDiv">
<behaviors>
<floatingBehavior handle="handleBar"/>
</behaviors>
</control>
</components>
</page>
</script>
0
相关文章
