推荐.NET教程: ASP.NET C# 开发环境 Ajax教程 控件开发 统计报表 数据库 Web服务 安装部署 CommunityServer NHibernate DataGrid/GridView 实用代码 VS2005
示例源码 MVC/三层 SqlHelper 入门源码 开源 CMS Ajax/Atlas C#.net 毕业设计 源码 经典代码 商业 本站作品 持久层 随书源码 WebService 英文/汉化 Asp.net2.0

阿牛·乐园

每天进步一点点

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  80 随笔 :: 14 文章 :: 389 评论 :: 13 引用
    如果刚从ASP过渡到ASPX的程序员,大都会抱怨ASPX生成的客户端元素的ID,太长了!如果要在客户端脚本中使用,如利用:
document.getElementById('Repeater1_ctl00_Button1')
这一类的方式来引用,非常不方便.
   


    想像一下,你想生成如上的界面,然后在鼠标在Button上mousemove时,改变其前面对应的文本框中的文字,格式为: 'hello world ' + 该Button的ID + '--' + new Date().valueOf()
    先不要管,这个有什么用,在什么地方用, 首先,你如何实现呢?

   我的实现方法就是如标题所言,用服务器控件来对付它们,只要我们来选择一个合适的思路:假设我们有一个服务器控件,通过给控件指定两个相关联的控件(这里就是Buton和TextBox),我们在客户端为这两个控件,分别设置自定义的属性来直接指向另一个控件.
   如果有了另一个控件的引用,我们就可以在button的实例中,直接得到相关联的TextBox的引用,而绕开getElementById().
   先看一下该服务端控件的使用:
   
 
    
<div>
        
<asp:Repeater ID="Repeater1" runat="server">
            
<ItemTemplate>
                
<asp:TextBox ID="TextBox1" runat="server" Width="445px"></asp:TextBox>
                
<asp:Button ID="Button1" runat="server" Text="Button" onmousemove="return button_onmousemove(this,event)" />
                
<cc1:WebControlLinker ID="WebControlLinker1" runat="server" WebControlFirst="Button1" WebControlSecond="TextBox1" />
            
</ItemTemplate>
        
</asp:Repeater>
        
    
</div>
 

    注意一下cc1:WebControlLinker WebControlFirst="Button1" WebControlSecond="TextBox1"  我们设置了两关联的控件.

    它们会在页面输出时,生成下面的代码:
页面呈现:
    <div>
        
                
<input name="Repeater1$ctl00$TextBox1" type="text" id="Repeater1_ctl00_TextBox1" style="width:445px;" />
                
<input type="submit" name="Repeater1$ctl00$Button1" value="Button" id="Repeater1_ctl00_Button1" onmousemove="return button_onmousemove(this,event)" />
                
<span id="Repeater1_ctl00_WebControlLinker1"></span>
            
                
<input name="Repeater1$ctl01$TextBox1" type="text" id="Repeater1_ctl01_TextBox1" style="width:445px;" />
                
<input type="submit" name="Repeater1$ctl01$Button1" value="Button" id="Repeater1_ctl01_Button1" onmousemove="return button_onmousemove(this,event)" />
                
<span id="Repeater1_ctl01_WebControlLinker1"></span>
            
                
<input name="Repeater1$ctl02$TextBox1" type="text" id="Repeater1_ctl02_TextBox1" style="width:445px;" />
                
<input type="submit" name="Repeater1$ctl02$Button1" value="Button" id="Repeater1_ctl02_Button1" onmousemove="return button_onmousemove(this,event)" />
                
<span id="Repeater1_ctl02_WebControlLinker1"></span>
            
                
<input name="Repeater1$ctl03$TextBox1" type="text" id="Repeater1_ctl03_TextBox1" style="width:445px;" />
                
<input type="submit" name="Repeater1$ctl03$Button1" value="Button" id="Repeater1_ctl03_Button1" onmousemove="return button_onmousemove(this,event)" />
                
<span id="Repeater1_ctl03_WebControlLinker1"></span>
            
                
<input name="Repeater1$ctl04$TextBox1" type="text" id="Repeater1_ctl04_TextBox1" style="width:445px;" />
                
<input type="submit" name="Repeater1$ctl04$Button1" value="Button" id="Repeater1_ctl04_Button1" onmousemove="return button_onmousemove(this,event)" />
                
<span id="Repeater1_ctl04_WebControlLinker1"></span>
            
        
    
</div>
和下面的关联引用用的脚本:  
<script type="text/javascript">
<!--
document.getElementById('Repeater1_ctl00_Button1').setAttribute('TextBox1',document.getElementById('Repeater1_ctl00_TextBox1'));
document.getElementById('Repeater1_ctl00_TextBox1').setAttribute('Button1',document.getElementById('Repeater1_ctl00_Button1'));
document.getElementById('Repeater1_ctl01_Button1').setAttribute('TextBox1',document.getElementById('Repeater1_ctl01_TextBox1'));
document.getElementById('Repeater1_ctl01_TextBox1').setAttribute('Button1',document.getElementById('Repeater1_ctl01_Button1'));
document.getElementById('Repeater1_ctl02_Button1').setAttribute('TextBox1',document.getElementById('Repeater1_ctl02_TextBox1'));
document.getElementById('Repeater1_ctl02_TextBox1').setAttribute('Button1',document.getElementById('Repeater1_ctl02_Button1'));
document.getElementById('Repeater1_ctl03_Button1').setAttribute('TextBox1',document.getElementById('Repeater1_ctl03_TextBox1'));
document.getElementById('Repeater1_ctl03_TextBox1').setAttribute('Button1',document.getElementById('Repeater1_ctl03_Button1'));
document.getElementById('Repeater1_ctl04_Button1').setAttribute('TextBox1',document.getElementById('Repeater1_ctl04_TextBox1'));
document.getElementById('Repeater1_ctl04_TextBox1').setAttribute('Button1',document.getElementById('Repeater1_ctl04_Button1'));
// -->
</script>
    有了上面的东西,我们要执行的脚本就可以简单的写成这样:
<head><title>
    Untitled Page
</title>
    
<script type="text/javascript">
        
function button_onmousemove(obj,e)
        
{
            obj.TextBox1.value 
= "hello world " + obj.TextBox1.Button1.id + '--'  + new Date().valueOf();;
        }

    
</script>

</head>
   obj.TextBox1.value 这种方式,访问,也挺爽吧?
附上求例下载:
WebControlLinker-demo.rar
posted on 2007-07-16 15:45 阿牛 阅读(1988) 评论(28)  编辑 收藏 网摘 所属分类: ASP.netDHTML,JS

评论

#1楼  2007-07-16 16:13 非我      
为什么不用ClientID呢
  回复  引用  查看    

#2楼 [楼主] 2007-07-16 16:24 阿牛      
@非我

在客户端,哪里有Clientid呀? 哈哈
我想你一定没有看懂.


  回复  引用  查看    

这个随机的控件名确实够郁闷的,
特别是用了ajax,
更是找不到控件名了。
  回复  引用    

#4楼  2007-07-16 16:46 菌哥      
对,用ClientID
  回复  引用  查看    

#5楼  2007-07-16 17:02 genson      
写一个控件派生自TextBox,在override方法里面使用ClientID属性。
  回复  引用  查看    

#6楼  2007-07-16 17:17 huobazi [未注册用户]
这么麻烦???
  回复  引用    

#7楼  2007-07-16 17:19 夜风      
可以理解成用 html 控件自定义属性 建立控件的关系。
  回复  引用  查看    

#8楼  2007-07-16 17:36 test [未注册用户]
test
  回复  引用    

#9楼  2007-07-16 17:47 JerryChou      
ClientID
  回复  引用  查看    

#10楼  2007-07-16 18:18 kisskiki [未注册用户]

@非我

在客户端,哪里有Clientid呀? 哈哈
我想你一定没有看懂.
onmousemove="return button_onmousemove(this,event)" />
clientid和你这里传this差不多的意思,不然照你这么说客户端也无法获得对应控件了
  回复  引用    

#11楼  2007-07-16 18:19 kisskiki [未注册用户]
◎另外说下,其实你写的这个东东应该放在新手区的。
  回复  引用    

#12楼  2007-07-16 19:08 Clingingboy      
很有用的东西
  回复  引用  查看    

#13楼  2007-07-16 19:23 随心所欲      
ClientId。
在服务器端构造js。
  回复  引用  查看    

#14楼  2007-07-16 22:24 Young      
晕!
var txt='<%=textbox1.ClientID%>';
alert(document.getElementById(txt).value)
  回复  引用  查看    

#15楼  2007-07-16 22:35 Young.J      
这样的文章还是赶快从首页拿掉的好,误导初学者!
  回复  引用  查看    

#16楼  2007-07-16 23:23 Artech      
个人觉得:
1. INamingContainer对于Render到Client的Html Tag的命名是有规律的,可以根据这个规律得到某个Client端Tag的名称。
2. 最有效的还是通过从Server端生成JS的方式,通过Server Side Control的ClientID将ID发送到Client。

  回复  引用  查看    

#17楼 [楼主] 2007-07-17 08:32 阿牛      
@夜风

看来还是你理解我的意思,握手
  回复  引用  查看    

#18楼 [楼主] 2007-07-17 08:34 阿牛      
@Artech

1. INamingContainer对于Render到Client的Html Tag的命名是有规律的,可以根据这个规律得到某个Client端Tag的名称。
2. 最有效的还是通过从Server端生成JS的方式,通过Server Side Control的ClientID将ID发送到Client。

原来一直这样用,其实对于解理了这种命名方式以后,怎么做都是可行的.

我的意思是,换一种思路,就是现在的思路去解决问题
  回复  引用  查看    

#19楼 [楼主] 2007-07-17 08:35 阿牛      
@Young
var txt='<%=textbox1.ClientID%>';
alert(document.getElementById(txt).value)

你这种方式得写在aspx页面中,不符合.net aspx的前后台分离的思想吧?
还有,如果用这种方式实现 Repeater中的两个控件的关联,也不是很容易


  回复  引用  查看    

#20楼 [楼主] 2007-07-17 08:38 阿牛      
@kisskiki

@非我
在客户端,哪里有Clientid呀? 哈哈
我想你一定没有看懂.
onmousemove="return button_onmousemove(this,event)" />
clientid和你这里传this差不多的意思,不然照你这么说客户端也无法获得对应控件了

ClientID是只在服务端才可以访问的属性
clientId和this更是不一样,一个是字串,一个是HTML元素的引用

如果你想告诉我,你可能通过ClientID来得到this,那,你得通过某一种途径把这个字串从服务端放置在客户端,这种方法,楼上的几位朋友已经列出好几种方法了




  回复  引用  查看    

#21楼 [楼主] 2007-07-17 08:40 阿牛      
@kisskiki

我感觉,这个思路是新思路,不是一种技艺,可以拿来与大家分享讨论,所以,还是首页了.

你原来是如何做的呢?新手作法,和高手作法都列出来好吗?
  回复  引用  查看    

#22楼 [楼主] 2007-07-17 08:42 阿牛      
@shop34480016

要是用Ajax了,请用
System.Web.UI.ScriptManager.RegisterStartupScript(Control control, Type type, string key, string script, bool addScriptTags)

来替换代码中的:
Page.ClientScript.
RegisterStartupScript(Type type, string key, string script, bool addScriptTags)

应该就可以工作了
  回复  引用  查看    

#23楼  2007-07-17 09:54 Jeffrey Zhao      
@阿牛
我一般会从服务器端输出ClientID到客户端。
  回复  引用  查看    

#24楼 [楼主] 2007-07-17 11:41 阿牛      
@Jeffrey Zhao

那要是像上面的例子,在一个Repeater中的Button和TextBox的ClientID呢?
如何更好的建立它们之时的关联呢?

要是输出ClientID到 window的一个属性上,也得是一个数组吧?

window.map = [{btn:btn1_ClientId,tb:tb1_ClientId},
[{btn:btn2_ClientId,tb:tb2_ClientId},
[{btn:btn3_ClientId,tb:tb3_ClientId},
[{btn:btn4_ClientId,tb:tb4_ClientId}];

是这种形式吗?还是?
  回复  引用  查看    

#25楼  2007-07-17 11:56 Clingingboy      
其实我不怎么的喜欢INamingContainer这个接口.这么多长长的id
  回复  引用  查看    

@阿牛
你可以在repeater的itemdatabound内输出Js(带clientid)到客户端
@Clingingboy
你不喜欢也没法 .net 内部要靠这个区分每个元素的

  回复  引用  查看    

#27楼 [楼主] 2007-07-17 22:50 阿牛      
@武眉博&lt;活靶子.Net&gt;
你可以在repeater的itemdatabound内输出Js(带clientid)到客户端

也行,但也得写代码。不过这样可以写一个函数来实现后期关联。

  回复  引用  查看    

#28楼  2007-07-18 07:19 蛙蛙池塘      
我一般也是在服务端生成带ClientID的代码
  回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-07-16 15:50 编辑过
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》



相关文章:

相关链接: