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

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

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

可移动的Div(1):MovableDiv
function MovableDiv(id) {
    this.obj = document.getElementById(id);

    this.obj.onmousedown = function() {
        if (event.srcElement != this) return;
        
        this._deltaX = event.x - this.offsetLeft;
        this._deltaY = event.y - this.offsetTop;
        this._dragging = true;
        this.setCapture();
    };

    this.obj.onmousemove = function() {
        if (this._dragging) {
            var x = event.x - this._deltaX;
            x = x < 0 ? 0 : x;
            var y = event.y - this._deltaY;
            y = y < 0 ? 0 : y;
            this.style.left = x + "px";
            this.style.top = y + "px";
        }
    };

    this.obj.onmouseup = function() {
        this._dragging = false;
        this.releaseCapture();
    };
}

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

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

可移动的Div(2):WidgetContainer
Type.registerNamespace("Monster");

Monster.WidgetContainer = function(element) {
    Monster.WidgetContainer.initializeBase(this, [element]);
    
    this._mouseDownDelegate = null;
    this._mouseMoveDelegate = null;
    this._mouseUpDelegate = null;
    this._dragging = false;
    this._deltaX = 0;
    this._deltaY = 0;
}

Monster.WidgetContainer.prototype = {

    initialize: function() {
        if (this._mouseDownDelegate === null) {
            this._mouseDownDelegate = Function.createDelegate(this, this._mouseDownHandler);
        }
        $addHandler(this.get_element(), "mousedown", this._mouseDownDelegate);

        if (this._mouseMoveDelegate === null) {
            this._mouseMoveDelegate = Function.createDelegate(this, this._mouseMoveHandler);
        }
        $addHandler(this.get_element(), "mousemove", this._mouseMoveDelegate);
        
        if (this._mouseUpDelegate === null) {
            this._mouseUpDelegate = Function.createDelegate(this, this._mouseUpHandler);
        }
        $addHandler(this.get_element(), "mouseup", this._mouseUpDelegate);
                
        Monster.WidgetContainer.callBaseMethod(this, "initialize");
    },
    
    dispose: function() {
        if (this._mouseDownDelegate) {
            $removeHandler(this.get_element(), "mousedown", this._mouseDownDelegate);
            delete this._moseDownDelegate;
        }
        
        if (this._mouseMoveDelegate) {
            $removeHandler(this.get_element(), "mousemove", this._mouseMoveDelegate);
            delete this._mouseMoveDelegate;
        }
        
        if (this._mouseUpDelegate) {
            $removeHandler(this.get_element(), "mouseup", this._mouseUpDelegate);
            delete this._mouseUpDelegate;
        }
        
        Monster.WidgetContainer.callBaseMethod(this, "dispose");
    },
    
    _mouseDownHandler: function(e) {
        this._dragging = true;
        this._deltaX = e.offsetX;
        this._deltaY = e.offsetY;
        this.get_element().setCapture();
    },
    
    _mouseMoveHandler: function(e) {
        if (!this._dragging) return;
        
        var left = this.get_element().offsetLeft + e.offsetX - this._deltaX;
        left = left < 0 ? 0 : left;
        var top = this.get_element().offsetTop + e.offsetY - this._deltaY;
        top = top < 0 ? 0 : top;
        Sys.UI.DomElement.setLocation(this.get_element(), left, top);
    },

    _mouseUpHandler: function(e) {
        if (this._dragging) {
            this._dragging = false;
            this.get_element().releaseCapture();
        }
    }
}

Monster.WidgetContainer.registerClass("Monster.WidgetContainer", Sys.UI.Control);

if (typeof(Sys) != "undefined") Sys.Application.notifyScriptLoaded();

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

创建WidgetContainer
<script type="text/javascript" language="javascript">
    function pageLoad(sender, args) {
        $create(Monster.WidgetContainer, { }, { }, null, $get("div1"));
    }
</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两个方法,用于初始化和资源释放,不过这样做有什么好处呢?即使我不释放好像也不会造成什么损失吧。有劳对此比较熟悉的大佬给我讲讲,嘿嘿@_@

ASP.NET AJAX Client Library: 更繁?更简?相关推荐

  1. Microsoft AJAX Client Library规范的实例

    MSDN 帮助: ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_vwdcon/html/285e3a65-b42e-42c5-952d-baf18405789 ...

  2. Custom Client Side Drag and Drop Behavior in ASP.NET AJAX

    这是我的一篇在http://aspalliance.com/上的英文文章,限于版权协议中的排他性条款,这里只能给出一部分摘要引用.有兴趣的朋友可以到这里看到完整的全文:<Custom Clien ...

  3. SharePoint 2010中的客户端AJAX应用——ASP.NET AJAX模板

    WCF Data Services是SharePoint 2010中一个极具吸引力的新特性.然而,因为它的强大,直接对其进行编程仍然会有点痛苦.幸运的是,一个新的相关技术 -- ASP.Net AJA ...

  4. 探讨ASP.NET AJAX客户端开发技术

    一. 简介     在ASP.NET AJAX组件开发中,存在许多环节有待我们深入挖掘.如何让ASP.NET AJAX服务端控件更有效地利用客户端脚本来为控件添加强大的客户端功能?如何更为方便地访问控 ...

  5. July 4th Links: ASP.NET, ASP.NET AJAX, Visual Studio, Silverlight and IIS7

    原文地址: http://weblogs.asp.net/scottgu/archive/2007/07/04/july-4th-links-asp-net-asp-net-ajax-visual-s ...

  6. 本周ASP.NET英文技术文章推荐[??/?? - 09/22]:VS 2008、.NET 3.5、asp:ListView、DotNetNuke、ASP.NET AJAX...

    摘要 本期共有7篇文章: 在Visual Studio 2008中使用ASP.NET AJAX Control Extender asp:ListView控件--第一部分,创建一个拥有干净CSS的产品 ...

  7. 理想的 ASP.NET AJAX (Part 1 - Client Centric)

    怎样的AJAX才算是理想? 要说什么是理想的ASP.NET AJAX,就要先说说什么是理想的AJAX.事实上AJAX最不理想的地方在于search engine friendly以及bookmarka ...

  8. 《ASP.NET AJAX程序设计——第II卷:客户端Microsoft AJAX Library相关》前言

    章节列表:http://www.cnblogs.com/dflying/archive/2007/05/18/751741.html 在最近的一年以及今后的三五年内,我们有理由相信Web应用程序将受到 ...

  9. 《ASP.NET AJAX程序设计——第II卷:客户端Microsoft AJAX Library与异步通讯层》前言...

    在最近的一年以及今后的三五年内,我们有理由相信Web应用程序将受到更多开发者和用户的青睐.作为领路人Google的一系列基于Web的产品完全地颠覆了传统的网页概念,让用户甚至不敢相信基于浏览器的程序竟 ...

最新文章

  1. 牛客网编程初学者入门训练 BC28
  2. 技术开发频道一周精选2007-8-24
  3. 获得主窗口句柄AfxGetApp()-m_pMainWnd
  4. PHP使用单例模式进行连接DB:public的方法进行调用连接函数即可
  5. 在WPF中显示动态GIF(转)
  6. 你的微博也被盗赞?试试HSTS强制HTTPS加密
  7. 一些非常有用的备忘录文档
  8. c# wpf 面试_WPF 基础面试题及答案(一)
  9. OpenCV进行图像相似度对比的几种办法
  10. android 多线程概述
  11. 离开(切换)当前页面时改变页面title
  12. leetcode-205-Isomorphic Strings
  13. python编码转换语句_将“ yield from”语句转换为Python 2.7代码
  14. mysql 在线优化工具_MySQL SQL查询优化工具EverSQL
  15. 【ArcGIS教程】土地利用转移矩阵及土地利用数据获取
  16. 有限自动机DFA 、 无限自动机NFA
  17. 【转载】《三体》:给时光以生命,给岁月以文明
  18. mysql 合并两个update_如何将多条update语句合并为一条
  19. SQL 语句集合(行转列,参数化...)
  20. SecureCRT for linux安装教学

热门文章

  1. 当RxJava遇到AOP
  2. codevs 1002 搭桥
  3. Mono项目宣布将整合F#
  4. Java 集合系列02之 Collection架构
  5. WordCount程序
  6. JavaScript机器学习之线性回归
  7. 解决tomcat was unable to start within问题
  8. CentOS 6.4安装配置LNMP服务器(Nginx+PHP+MySQL)
  9. 分布式服务框架 dubbo/dubbox 入门示例(转)
  10. 平台数据库导入导出快捷工具说明