众所周知在Asp.net中如果一个页面添加了一个用户控件(或母版页),那么用户控件内的控件的 ClientID号会被自动添加页面中用户控件的ClientID
即页面中的控件内的控件ClientID=用户控件id号+"_"+用户控件内控件的id号
说的太绕了,还是看下例子吧
在一个asp.net页面index.aspx中添加了一个head.ascx用户控件id号为"head1"
head.ascx控件中有一个input#hid_name控件
那么index.aspx最终生成的input的id为"head1_hid_name"
MS为什么要这样设计?
主要是asp.net中所有的控件都有一个唯一的id号(包括ClientID),当页面回发时.net可以通过该id号来进行回发后的后续处理
而如果一个页面中包含了多个用户控件,有可能一个用户控件中的id号是唯一的,但当合并到一个页面中的时候就有可能导致会出现重复的id号
所以asp.net就会在每个用户控件中的id前添加该用户控件的id,这样在一个页面中就不会出现重复的id号(一个页面如果出现重复的id号是编译通过的)
解决方案:
因为某些原因我们可能需要使用真正的用户控件中的控件id
如已经写好的js事件,css样式等
所以我们需要恢复原来的控件id号,有以下方案
1.修改现在的js文件和css文件使用class来进行处理,但这种方式太不靠谱
2.写一个js文件将asp.net生成的id号替换成掉用户控件id号,在每个使用的页面中引用即可
如果有回发需求可以在回发之前恢复asp.net生成的clientid号这样就不会影响asp.net的回发处理
//htl add 2014-12-25 //页面中用户控件的id号 var _id = 'details1_'; //将用户控件中的控件id中的用户控件id替换掉 jQuery("[id*=" + _id + "]").each(function($) { $(this).attr("id", $(this).attr("id").replace(_id, "")); //添加自定义属性,用于在回发之前恢复asp.net生成的id号 $(this).attr('usercontrol', ''); }); //在回发之前恢复asp.net生成的id号 jQuery("form").submit(function() { jQuery("[usercontrol]").each(function() { $(this).attr("id", _id + $(this).attr("id")); }); });
3.在asp.net页面中通过代码进行替换,此方式将导致在回发时会无法找到对应的控件id而导致无法找到真正的控件而影响业务处理
/// <summary> /// htl add 2014-12-25 /// 恢复用户控件中控件的ClientID号 /// 原因是在页面中调用用户控件时,用户控件里的控件的ClientID会被自动添加用户控件id /// </summary> /// <param name="writer"></param> protectedoverridevoidRender(HtmlTextWriter writer) { System.IO.StringWriter sw = newSystem.IO.StringWriter(); base.Render(newHtmlTextWriter(sw)); //获取正常输出的html,包含__VIEWSTATE //过滤掉该控件的ClientID号恢复用户控件内的控件的ClientID //注意过滤掉后会导致在回发时无法找到真正的控件 writer.WriteLine(Web.PageHelp.RegexStr(@details1.ClientID + "_", sw.ToString()).Trim()); }
参考: