文本版|topic 高级搜索
   名人堂 帮助 论坛制度 意见反馈 | 首页 博客 周新贴 招聘 专题 新闻
RSS 底部
 
社区导航: 专家门诊   网络技术   操作系统   数据库   程序设计   系统应用   考试认证   CIO及信息化   站长交流   综合交流   下载基地  51CTO产品服务 设为首页 | 收藏本站
51CTO技术论坛» .Net » 设计有复杂客户端Script的服务器控件       [ 打印]  [ 订阅]  [ 收藏]  [ 推荐给朋友]   [ 本帖文本页]

论坛跳转:
     
标题: [转载] 设计有复杂客户端Script的服务器控件  ( 查看:207  回复:0 )   
 
Easy
助理工程师  点击可查看详细



帖子 365
精华 2
无忧币 1770
积分 1609
阅读权限 40
注册日期 2007-11-6
最后登录 2008-5-5 离线

[查看资料]  [发短消息]  [Blog
       
发表于:2007-11-21 14:27   标题:设计有复杂客户端Script的服务器控件
上一帖 |
使用ASP.NET的服务器控件,可以极大的提高我们Web开发中组件的复用性。不过由于ASP.NET默认的__doPostBack传输机制,对于我们在Web页上开发DHMTL特性的功能没有什么实质的帮助,因为我们不可能每次HTML属性修改都doPostBack,这样的效率和用户体验会死人的哦~~

    所以这时候使用客户端Script是一个很好的办法。那我们就用呗,可是问题就谁之而来了。使用Script来操作DHTML,需要获得被操作HTML元素对象的引用(废话,不然怎么操作?!)。我们最常用的方法是:使用HTML元素的ID来引用或者使用document对象的方法:getElementById、getElementsByName 和 getElementsByTagName。由于getElementsByName 和 getElementsByTagName获得的都是一个HTML元素对象集合,所以最常用的就是getElementById了。可是对于ASP.NET的服务器端控件,要在该控件PreRender的时候才能准确的获得其ClientID属性。而且就算我们取到了HTML元素的ID,我们还需要把这个ID hard-coding到被Register到页面的Script里去。这里的复杂程度就可大可小很难说了。

    这样一来每次修改Script都要很麻烦的到控件的RegisterClientScript方法里去修改Script,并处理好需要动态写入Script的参数。更麻烦的是如果页面允许多个这样的控件Render,还需要考虑会不会ID冲突等问题,虽然ASP.NET控件Render时候会自动保证控件和其子控件的ID是unique的,可是其它的HTML元素就比较的麻烦了。而且大量的ID使用,也会给Web的设计带来一些小麻烦,因为也存在需要避免ID重复的问题。

    所以在我管理有复杂客户端Script的服务器控件时,我都不给其中的HTML元素设置ID,并且也不在客户端脚本中使用任何和HTML元素ID有关的方法去引用它们。那么怎么引用呢?使用HTML元素在DHTML对象树中的Hierarchy来查找它们就行了。当我们在IE中操作这个"控件"(已经就是HTML元素了)时,在该控件最外层作为container的HTML元素里俘获event,然后使用其event.srcElement,就可以以它为起点来查找需要的HTML元素了。比如: <table border="1" ondblclick="ShowOrHideSpan(this)" style="border-collapse: collapse;">
    <tr>
         <td name="title">
             Tilte</td>
    </tr>
    <tr>
         <td>
             <span>Content: asdf asdf asdf</span></td>
    </tr>
</table>我们想实现double click表格中的Title来隐藏或显示Content,怎么弄呢?

    使用如下JScript代码: <script language="javascript">
function ShowOrHideSpan(elmt)
{
    var srcElmt = event.srcElement;
    if ( srcElmt && srcElmt.tagName == 'TD' && srcElmt.name == 'title' )
    {
         var span = FindChildElement(elmt, 'SPAN');
         if ( span.style.display == 'none' )
         {
              span.style.display = 'inline';
         }
         else
         {
              span.style.display = 'none';
         }      
    }   
}
</script>    这段Script中的FindChildElement(elmt, 'SPAN')就是在以elmt为起点遍历DHMTL对象树,一找出SPAN元素。当然这个示例只是一个demo,或许你会说,把事件监听放到第一个tr上多好,可那不是我们在这个demo中关心的东西。在实际的控件开发中可能会比这复杂的多,不过原理就是这样弄了,完全不依赖任何的ID。

    不过这种方式也还是有些不足,因为有时我们会发现FindChildElement相对于FindParentElement不是那么容易确定,一个起点元素的parent肯定是唯一的,而它的child显然可能是很多个。不过在我觉得在控件开发中注意一下HTML元素的Hierarchy比管理它们ID要容易得多,而且也不会对Script产生太大的影响。

    欢迎您的讨论和建议~~

    附一、FindChildElement(element, tagName)源代码(先深遍历):
<script lanuage="JavaScript">
function FindChildElement(element, tagName)
{
    var isFounded = false;
    var elements = element;
    var result = element;
    if ( element.tagName == tagName )
    {
        return element;
    }
    while(!isFounded && elements != null && result != null && result.tagName != tagName)
    {
        elements = elements.childNodes;
        for( var i=0 ; elements != null && i < elements.length ; i++ )
        {
            result = elements.item(i);
            var result2 = FindChildElement(result, tagName);
            if ( result == null || result2 == null )
            {
                continue;
            }
            if ( result.tagName == tagName || result2.tagName == tagName )
            {
                if ( result2.tagName == tagName )
                {
                    result = result2;
                }
                isFounded = true;
                break;
            }
        }
    }
    if ( isFounded )
    {
        return result;
    }
    else
    {
        return null;
    }
}
</script>    在某些时候我们可以不用这个遍历算法,而使用element.all.tags(tagName)来获取Child Element,这个依赖于该页面的HTML元素之间的Hierarchy。

    附二、FindParentElement(element, tagName)源代码: <script lanuage="JavaScript">
function FindParentElement(element, tagName)
{
    while(element != null && element.tagName != tagName )
    {
        element = element.parentElement;
    }
    if ( element != null && element.tagName == tagName )
    {
        return element;
    }
    return null;
}
</script>



网络工程师到底该不该去考CCIE认证?
2007-11-21 14:271楼
[ 顶部 ]
     
论坛跳转:  

| | |

标记已读 · 删除论坛Cookies · 文本版 · WAP
 
| 诚征版主 | 版主堂 | 意见建议 | 大史记 | 论坛地图
Copyright©2005-2008 51CTO.COM  Powered by Discuz!
本论坛言论纯属发布者个人意见,不代表51CTO网站立场!如有疑义,请与管理员联系。
京ICP备05051492号