本想把该指南一次发表,这样各位同仁看起来也方便点,但是也许是文章稍长就是不能,希望各位朋友能够谅解!!!
原文地址:http://www.codeproject.com/aspnet/ajax_scribble.asp
源代码:http://www.codeproject.com/aspnet/ajax_scribble/ajax_scribble_src.zip
Atlas指南: 建立一个AJAX 涂鸦程序(三)
Scribble.js
我们有服务器端的image handler和服务器端的web服务更新image。现在我们需要客户端脚本,它们能够从鼠标事件中捕捉到的点发送到服务器的web服务。
1. 在工程的资源管理器中高亮(译者注:也就选中的意思)ScriptLibrary 文件夹。
2. 在WebSite 菜单点击Add New Item 或者按下 Ctrl + Shift + A.
3. 在 Add New Item对话框中选择JScript File, 确认名称为Scribble.js 并点击OK.
4. 接下来你必需声明一些全局变量。在scribble的第一个版本中我们用的是全局变量,但在以后的版本我们将使用JavaScript对象。
//The HTML image element that is to be drawn
var image;
//The source of the image
var originalSrc;
//The number of iteration
var iter = 0;
//The array of points
var points = null;
上面的对各声明的变量的注释描述了目的。Iter变量用来在绘画请求向服务器发送之后更改image的源。假设IE设置image.src = image.src 会刷新image但是同样的代码在Firefox中就不能正常工作了,为了解决这个问题,我们维护一个变量iter,每次我们向web服务发送一个Draw 请求它就增加,我们把迭代数量放在一个originalSrc (译者认为这里应该是iter,而不是originalSrc)变量中,因此浏览器认为它需要请求服务器刷新数据拒绝使用缓存的image。
5. 我们定义函数 startStroke ,它响应鼠标mousedown 事件开始一次绘制动作。
function startStroke()
{
points = new Array();
window.event.returnValue = false;
}
当新的笔画开始时,我们建立一组由第一根线指示出的新的点,第二根线取消事件的默认行为,这是有必要的,因为针对image的mousedown事件的默认行为是开始拖操作,这阻止了引发任何进一步的事件。
6. 当响应mouseup 事件或者 mouseout 事件笔画结束的时候,我们需要对web服务进行一次实际的调用,这些是在函数endStroke 中完成。
function endStroke()
{
if (!points || points.length < 2)
return true;
//Send the points to the webservice
ScribbleService.Draw(points, onWebMethodComplete,
onWebMethodTimeout, onWebMethodError);
points = null;
window.event.returnValue = false;
}
在这个函数中惟一感兴趣的一行就是
ScribbleService.Draw(points, onWebMethodComplete, onWebMethodTimeout, onWebMethodError);,它异步调用web服务ScribbleService.asmx中的方法Draw。 由于有Atlas框架,该函数对我们来说是自动可用的。
7. onWebMethodError 是一个被Atlas框架调用的函数,当web服务方法发生错误时被调用,还有当web方法调用超过定义在Atlas框架中一个可以配置的时间时,onWebMethodTimeout函数被调用。在这个版本中我们只向用户显示一个有错误文本的的消息框。
function onWebMethodError(fault)
{
alert("Error occured:\n" + fault.get_message());
}
function onWebMethodTimeout()
{
alert("Timeout occured");
}
8. onWebMethodComplete 函数是当web方法调用成功后被调用的一个函数,当该函数被调用Image需要被重新加载。
function onWebMethodComplete(result, response, context)
{
//We need to refresh the image
var shimImage = new Image(200, 200);
shimImage.src = originalSrc + "?" + iter++;
shimImage.onload = function()
{
image.src = shimImage.src;
}
}
我们建立一个Image对象shimImage并设置它的源为我们正在画的image的原始源。当image对象加载的时候,我们把在页面的实际的HTML image元素的源设置为临时image对象的源。这样做是当替换image时避免闪动。
我们需要在mousemove事件期间填充点的数组,用addPoints 函数完成。.
function addPoints()
{
if (points)
{
var point = { X : window.event.offsetX,
Y : window.event.offsetY};
points.push(point);
if (points.length == 3)
{
endStroke();
points = new Array();
points.push(point);
}
window.event.returnValue = false;
}
}
o 用事件对象的offsetX 和 offsetY熟悉构建一个新的point对象,然后把它加入points数组,offsetX and offsetY属性给出了相关的引发事件的HTML元素的相对位置。
o 如果数组的长度达到了3,我们自动请求服务器进行一次绘制操作,并重置points数组,这样做就能让用户在释放鼠标按钮之前看到绘制。
9. 最后,我们需要注册(hook)这些事件,这是在pageLoad 函数中完成的。
function pageLoad()
{
var surface = document.getElementById("drawingSurface");
image = surface.getElementsByTagName("IMG")[0];
originalSrc = image.src;
surface.attachEvent("onmousedown", startStroke);
surface.attachEvent("onmouseup", endStroke);
surface.attachEvent("onmouseout", endStroke);
surface.attachEvent("onmousemove", addPoints);
}
o pageLoad 函数是一个特殊的函数,当Atlas框架已经加载完成的时候调用。我们用这代替规则的window或body加载事件,这样的话我们能确保Atlas完成了加载。
o 那实际的被绘制的image元素被安置在一个id是drawingSurface的div标签中,div的size与image的size是相同的,所有我们能安全的把事件附加在该div上。
Default.aspx
个别的程序组件需要配置在Default.aspx 页面中.这就是该页面的代码。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Atlas Scribble Sample</title>
</head>
<body>
<form id="form1" runat="server">
<Atlas:ScriptManager ID="AtlasScriptManager" runat="server"
EnableScriptComponents="False" >
<Services>
<Atlas:ServiceReference Path="ScribbleService.asmx" />
</Services>
<Scripts>
<Atlas:ScriptReference Path="ScriptLibrary/Scribble.js" />
</Scripts>
</Atlas:ScriptManager>
<div id="drawingSurface"
style="border:solid 1px black;height:200px;width:200px">
<img alt="Scribble" src="ScribbleImage.ashx"
style="height:200px;width:200px" galleryimg="false" />
</div>
</form>
</body>
</html>
这个页面中非常重要的一个地方就是atlas:ScriptManager server control. The ScriptManager 服务器控件,它为Atlas和任何web服务代理脚本生成客户端脚本块。让我们考察下在Default.aspx 页面中ScriptManager控件的用法。
- EnableScriptComponents 属性被设置成false。这就是参考AtlasRuntime.js 而不是Atlas.js生成客户端脚本块。在scribble的这个版本中我们没有用到Atlas的组件和控件,所以我们宁愿使用的Atlas框架的轻量级版本。
- 我们增加一个对ScribbleService.asmx web 服务的服务引用。这将向客户端脚本生中为web服务代理生成一个URL引用。
- 我们增加另一个对Scribble.js 的脚本引用。
这就把各个方面都组合起来了,现在你能编译运行工程了。我鼓励你取看看通过Atlas Script Manager生成的实际的客户端html代码。
The Atlas Magic
这儿就是Atlas框架为我们所做的。
- 不需要特殊的努力就允许我们写出跨浏览器的web应用程序。不管在IE上还是在Firefox上web服务调用和客户端自动事件处理都能工作,Atlas框架针对Firefox对象增加必要的JavaScript原型(prototype),使得它们就跟IE对象一样。IE特殊的函数如attachEvent以及event.offsetX和event.offsetY属性在Firefox中都是可用的。你可用在AtlasCompat.js文件中查看,这些是如何实现的。
- 自动为Scribble程序的web方法建立一个JavaScript代理。为ScribbleService.asmx 文件建立的JavaScript代理脚本有ScribbleService.asmx/js的URL.这是添加在web.config中的HTTP module生成的。
Where are We
我们已经明白使用Atlas轻松地如何调用web服务以及如何写出跨浏览器的程序。在以后的指南中,我们将看到更多的Atlas客户端控件以及声明编程(依赖于用户的反馈!)。如果你喜欢该指南,请自由地书写一个评论。如果你不喜欢它,请写一个评论如何去改进它。
下载和运行源代码
因为Atlas仍然不是可再分发的,我没有在下载的源码中包含Atlas文件。让下载的代码能工作,下面是你需要做的事情。
- 你需要从 Atlas Web Site下载Atlas.
- 在你下载完Atlas空白工程模板后,你可以通过 File->new-> Web Site 建立一个新的web站点。
- 把压缩的源文件解压到刚才新建的工程目录下,并覆盖以及存在的文件。
- 在 Website 菜单中选中 Add Existing Item, 从web站点的根目录中添加 ScribbleService.asmx 和 ScribbleImage.ashx ,还有从ScriptLibrary 文件夹中添加Scribble.js.
- 编译并运行web站点.
完了!!