ASP.NET AJAX Client Library: 更繁?更简?

本文对比了使用原始 JavaScript 和 ASP.NET AJAX 实现拖拽效果的方法。通过具体的代码示例,展示了两种方式的不同之处及实现难度。

这两周周末终于决定忙里偷闲,利用业余时间好好学习ASP.NET AJAX,虽然服务器端控件比如UpdatePanel、Timer等很好用,不过总感觉雾里看花,没法看到ASP.NET AJAX的原貌,所以决定花些时间学习它的Client Library。断断续续看了一些资料,在稍微了解大概之后决定用它写点东西检验一下学习成果,毕竟实际动手才能证明我确实掌握了这门技术,而不仅是纸上谈兵,呵呵。

拖拽效果目前非常流行,比如Pageflakes、protopage等都频繁使用了这项技术用以改善用户体验并且获得良好的赞誉。很多人对这项技术深感恐惧,好像它是一门极为高深的技术,我在很多论坛上看到好些人都在“冰天雪地裸体后空翻720度”求教具体如何实现,实际上这项技术本身并不复杂,简单的拖拽效果区区几十行代码就可以搞定了。下面就简单实现一个拖拽DIV的效果。

首先不考虑ASP.NET AJAX,用最原始的Javascript来实现我们想要的效果,区区二十余行代码就可以了,相信任何有点Javascript基础的同志都可以看得很明白,因此我就不多说了,贴代码了事:

ContractedBlock.gifExpandedBlockStart.gif可移动的Div(1):MovableDiv
ExpandedBlockStart.gifContractedBlock.giffunction MovableDiv(id) dot.gif{
InBlock.gif    
this.obj = document.getElementById(id);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.obj.onmousedown = function() dot.gif{
InBlock.gif        
if (event.srcElement != thisreturn;
InBlock.gif        
InBlock.gif        
this._deltaX = event.x - this.offsetLeft;
InBlock.gif        
this._deltaY = event.y - this.offsetTop;
InBlock.gif        
this._dragging = true;
InBlock.gif        
this.setCapture();
ExpandedSubBlockEnd.gif    }
;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.obj.onmousemove = function() dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (this._dragging) dot.gif{
InBlock.gif            
var x = event.x - this._deltaX;
InBlock.gif            x 
= x < 0 ? 0 : x;
InBlock.gif            
var y = event.y - this._deltaY;
InBlock.gif            y 
= y < 0 ? 0 : y;
InBlock.gif            
this.style.left = x + "px";
InBlock.gif            
this.style.top = y + "px";
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }
;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.obj.onmouseup = function() dot.gif{
InBlock.gif        
this._dragging = false;
InBlock.gif        
this.releaseCapture();
ExpandedSubBlockEnd.gif    }
;
ExpandedBlockEnd.gif}

具体使用时就是实例化一个MovableDiv对象即可,如"new MovableDiv('div1');"。当然,记得给div1设置position为“absolute”,否则有啥意外我概不负责,呵呵!

好,上面代码完全没有使用任何ASP.NET AJAX的特性,下面利用ASP.NET AJAX Client Library提供的机制实现完全相同功能,呵呵,解释这些代码实在费劲,而且现在不是提倡“代码即文档”嘛,相信大家的能力以及我的编码规范程度(自恋一把,喉喉),同样贴出代码如下:

ContractedBlock.gifExpandedBlockStart.gif可移动的Div(2):WidgetContainer
None.gifType.registerNamespace("Monster");
None.gif
ExpandedBlockStart.gifContractedBlock.gifMonster.WidgetContainer 
= function(element) dot.gif{
InBlock.gif    Monster.WidgetContainer.initializeBase(
this, [element]);
InBlock.gif    
InBlock.gif    
this._mouseDownDelegate = null;
InBlock.gif    
this._mouseMoveDelegate = null;
InBlock.gif    
this._mouseUpDelegate = null;
InBlock.gif    
this._dragging = false;
InBlock.gif    
this._deltaX = 0;
InBlock.gif    
this._deltaY = 0;
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gifMonster.WidgetContainer.prototype 
= dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    initialize: 
function() dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (this._mouseDownDelegate === nulldot.gif{
InBlock.gif            
this._mouseDownDelegate = Function.createDelegate(thisthis._mouseDownHandler);
ExpandedSubBlockEnd.gif        }

InBlock.gif        $addHandler(
this.get_element(), "mousedown"this._mouseDownDelegate);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (this._mouseMoveDelegate === nulldot.gif{
InBlock.gif            
this._mouseMoveDelegate = Function.createDelegate(thisthis._mouseMoveHandler);
ExpandedSubBlockEnd.gif        }

InBlock.gif        $addHandler(
this.get_element(), "mousemove"this._mouseMoveDelegate);
InBlock.gif        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (this._mouseUpDelegate === nulldot.gif{
InBlock.gif            
this._mouseUpDelegate = Function.createDelegate(thisthis._mouseUpHandler);
ExpandedSubBlockEnd.gif        }

InBlock.gif        $addHandler(
this.get_element(), "mouseup"this._mouseUpDelegate);
InBlock.gif                
InBlock.gif        Monster.WidgetContainer.callBaseMethod(
this"initialize");
ExpandedSubBlockEnd.gif    }
,
InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    dispose: 
function() dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (this._mouseDownDelegate) dot.gif{
InBlock.gif            $removeHandler(
this.get_element(), "mousedown"this._mouseDownDelegate);
InBlock.gif            
delete this._moseDownDelegate;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (this._mouseMoveDelegate) dot.gif{
InBlock.gif            $removeHandler(
this.get_element(), "mousemove"this._mouseMoveDelegate);
InBlock.gif            
delete this._mouseMoveDelegate;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (this._mouseUpDelegate) dot.gif{
InBlock.gif            $removeHandler(
this.get_element(), "mouseup"this._mouseUpDelegate);
InBlock.gif            
delete this._mouseUpDelegate;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        Monster.WidgetContainer.callBaseMethod(
this"dispose");
ExpandedSubBlockEnd.gif    }
,
InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    _mouseDownHandler: 
function(e) dot.gif{
InBlock.gif        
this._dragging = true;
InBlock.gif        
this._deltaX = e.offsetX;
InBlock.gif        
this._deltaY = e.offsetY;
InBlock.gif        
this.get_element().setCapture();
ExpandedSubBlockEnd.gif    }
,
InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    _mouseMoveHandler: 
function(e) dot.gif{
InBlock.gif        
if (!this._dragging) return;
InBlock.gif        
InBlock.gif        
var left = this.get_element().offsetLeft + e.offsetX - this._deltaX;
InBlock.gif        left 
= left < 0 ? 0 : left;
InBlock.gif        
var top = this.get_element().offsetTop + e.offsetY - this._deltaY;
InBlock.gif        top 
= top < 0 ? 0 : top;
InBlock.gif        Sys.UI.DomElement.setLocation(
this.get_element(), left, top);
ExpandedSubBlockEnd.gif    }
,
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    _mouseUpHandler: 
function(e) dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (this._dragging) dot.gif{
InBlock.gif            
this._dragging = false;
InBlock.gif            
this.get_element().releaseCapture();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gifMonster.WidgetContainer.registerClass(
"Monster.WidgetContainer", Sys.UI.Control);
None.gif
None.gif
if (typeof(Sys) != "undefined") Sys.Application.notifyScriptLoaded();

同样,列出使用方法如下,这里使用了“$create”进行创建,这是创建Sys.Component及其子类如Sys.UI.Control等的简写形式:

ContractedBlock.gifExpandedBlockStart.gif创建WidgetContainer
None.gif<script type="text/javascript" language="javascript">
ExpandedBlockStart.gifContractedBlock.gif    
function pageLoad(sender, args) dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        $create(Monster.WidgetContainer, 
dot.gif{ }dot.gif{ }null, $get("div1"));
ExpandedBlockEnd.gif    }

None.gif
</script>

在写的过程中我就暗暗皱眉,怎么写了半天还没完?在没用ASP.NET AJAX Client Library之前,我3分钟就把移动效果运行起来了,而现在10分钟都过去了还没搞定!写完一对比,代码量多出N倍,为了实现相同的效果,我居然写了近80行代码,晕死!虽然看起来更OO些,非常像C#这种高级语言,但是这样的效果值得吗?对于熟悉Javascript的开发人员而言,说不定第一种写法更加直观呢!前一阵子不知在什么地方看到这样的评论:ASP.NET AJAX Client Library对JavaScript的封装接近病态!是不是真的如此我不知道,不过从开发效率而言似乎反而降低了?!也许这种写法对后期维护有好处,这也许能弥补一部分损失吧,不过我还是不知道!

注:WidgetContainer是MovableDiv的翻版,但是不知道为什么,如果拖动WidgetContainer所代表的div到浏览器窗口的右边缘或下边缘外,就会出现很诡异的现象,目前位置还不明白为什么,有心的同志可以帮忙看看,谢谢先!

附:由于使用了setCapture和releaseCapture,因此上面的代码只能在IE浏览器中运行。

update @07.04.11 13:48
不过,再仔细看看,在ASP.NET AJAX方式的实现中也就是多了initialize和dispose两个方法,用于初始化和资源释放,不过这样做有什么好处呢?即使我不释放好像也不会造成什么损失吧。有劳对此比较熟悉的大佬给我讲讲,嘿嘿@_@

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值