为啥 ASP.Net RadioButton 和 CheckBox 在 Span 内呈现?
Posted
技术标签:
【中文标题】为啥 ASP.Net RadioButton 和 CheckBox 在 Span 内呈现?【英文标题】:Why does ASP.Net RadioButton and CheckBox render inside a Span?为什么 ASP.Net RadioButton 和 CheckBox 在 Span 内呈现? 【发布时间】:2010-11-03 02:20:52 【问题描述】:我希望这样:
<asp:CheckBox ID="CheckBox1" runat="server" CssClass="myClass" />
<asp:RadioButton ID="RadioButton1" runat="server" CssClass="myClass" />
<asp:TextBox ID="TextBox1" runat="server" CssClass="myClass" />
...像这样渲染 (为简单起见删除了一些属性):
<input id="CheckBox1" type="checkbox" class="myClass" />
<input id="RadioButton1" type="radio" class="myClass" />
<input id="TextBox1" type="text" class="myClass" />
...事实上,RadioButton
和 CheckBox
被 span
标签包裹,并且 CSS 类被应用在那里。
<span class="myClass"><input id="CheckBox1" type="checkbox" /></span>
<span class="myClass"><input id="RadioButton1" type="radio" /></span>
<input type="text" id="TextBox1" class="myClass" />
这是有原因的吗?有办法避免吗?它使 jQuery 选择器变得丑陋,因为您无法捕获所有选择器:
$("input.myClass")
当然它只是:
$("input.myClass, span.myClass input")
...但这很难看。我可以编写自己的选择器,但还是没有应有的优雅。
【问题讨论】:
不是答案,只是表示同情——几年前我第一次开始在 .NET 平台上工作并使用 JS 找出复选框的值时,我花了几个小时试图弄清楚为什么我的价值观没有引起警觉。你猜怎么着——跨度标签。我一直想知道为什么 MS 为他们的单选按钮和复选框添加了冗余标签! @Hardwareguy 有时这是跨度,有时是输入。那就是问题所在。 $("input.myclass") 可能有点过于具体,但 $(".myClass") 会让你同样头疼。 如果您使用 Checkbox.Text 属性,则会添加一个标签。然后跨度将围绕它们,并且样式适用于两者。这就是周围跨度的原因。 可能是因为这样的事情:***.com/questions/7398462/… 对于 asp:checkbox,我注意到使用 CssClass 属性时也会添加跨度。 【参考方案1】:在我找到 inputAttributes 属性之前,这也让我发疯了。
例如,这里是如何直接在复选框控件上添加一个类,而不需要跨度废话:
myCheckBoxControl.InputAttributes.Add("class", "myCheckBoxClass")
【讨论】:
如果可以,我会给 +100,因为我不能给 +1 :) 谢谢! 很好地找到了这个。另请注意,LabelAttributes
会相应地设置相应复选框标签的样式。
这很奇怪,因为myCheckBoxControl.Attributes.Add
将触发与myCheckBoxControl.CssClass
相同的行为,它将其包装在<span>
标记中,但myCheckBoxControl.InputAttributes.Add
不会 - 耶!
不幸的是,使用此方法添加的类不会在视图状态中捕获,而使用 CssClass 添加的类会在视图状态中捕获。
在哪里添加这个。我无法在 c# 后面的代码中获取 InputAttributes【参考方案2】:
System.Web.UI.WebControls
命名空间中的 Web 控件在不同浏览器中的呈现方式可能不同。你不能指望他们总是渲染相同的元素。他们可能会添加任何他们认为需要使其在特定浏览器中运行的内容。
如果您想控制控件如何呈现为 html,则应改用 System.Web.UI.HtmlControls
命名空间中的控件。那就是:
<input type="checkbox" id="CheckBox1" runat="server" class="myClass" />
<input type="radio" name="RadioButton1" runat="server" class="myClass" />
<input type="text" id="TextBox1" runat="server" class="myClass" />
它们将像相应的 html 元素一样呈现,没有添加额外的元素。这当然意味着您必须对浏览器的兼容性负责,而控件则不需要。此外,这些控件不具备 WebControls
命名空间中控件的所有功能。
【讨论】:
发生了多少回发,我认为这会更令人头疼。我同意我们应该默认使用这些控件,并在需要时升级到 WebControls。 如果你打算这样做,你还不如只使用 ASP.Net MVC ;) @womp 我希望这是一个选项。【参考方案3】:默认情况下,每个 WebControl 都呈现为 <span>
标记,以及控件作者添加的任何自定义呈现。
在编写自定义 WebControl 时,您通常要做的第一件事就是覆盖“TagKey”属性以呈现 div 或跨度以外的其他内容。该属性的默认值为 HtmlTextWriterTag.Span。
您可以将您的复选框项目子类化并覆盖 TagKey 属性以呈现其他内容,但是您必须处理将所有复选框变成您自己的版本。
【讨论】:
我猜你必须选择你的毒药。丑陋的 jQuery 选择器或零星的子类控件以实现一致的渲染。如果 all 输入控件使用跨度呈现,我会很酷。一致性是一件不错的事情。【参考方案4】:我遇到了这个问题,并尝试使用控制适配器解决它。
有关对单选按钮列表执行此操作的示例,请参阅 here。
我最终将它作为我的 RadioButtonAdaptor-
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.Adapters;
public class RadioButtonAdapter : WebControlAdapter
protected override void Render(HtmlTextWriter writer)
RadioButton targetControl = this.Control as RadioButton;
if (targetControl == null)
base.Render(writer);
return;
writer.WriteBeginTag("input");
writer.WriteAttribute("type", "radio");
writer.WriteAttribute("name", targetControl.GroupName);
writer.WriteAttribute("id", targetControl.ClientID);
if (targetControl.CssClass.Length > 0)
writer.WriteAttribute("class", targetControl.CssClass);
writer.Write(" />");
这已添加到我的浏览器文件中-
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.RadioButton"
adapterType="RadioButtonAdapter" />
</controlAdapters>
</browser>
当然,这也有一些缺点。与the above link 中提到的那些一样,如果您不隐含所有内容,您也会失去功能(上面的代码不允许检查单选按钮)。有一些 CSS 友好的控件适配器,但它们不包括单选按钮控件。或许可以使用Reflector来获取默认的控制适配器作为起点。
【讨论】:
我喜欢这个建议!我知道迟到的评论,但这对我今天帮助很大!【参考方案5】:普通的 RadioButton 通常在没有跨度的情况下呈现。如果设置了 CssClass、Style、Enabled 属性,RadioButton 会以跨度呈现。当我需要使用客户端脚本操作单选按钮时,这种不一致是一个真正的痛苦。我通常做的是应用一个虚拟的 CssClass,以便它始终一致地呈现一个跨度。
【讨论】:
【参考方案6】:我认为最好的方法是:
public class HtmlTextWriterNoSpan : HtmlTextWriter
public HtmlTextWriterNoSpan(TextWriter textWriter) : base(textWriter)
protected override bool OnTagRender(string name, HtmlTextWriterTag key)
if (name == HtmlTextWriterTag.Span)
return false;
return base.OnTagRender(name, key);
在自定义控件中使用它:
protected override void Render(HtmlTextWriter writer)
writer = new HtmlTextWriterNoSpan(writer);
base.Render(writer);
// HERE MORE CODE
【讨论】:
我喜欢那个【参考方案7】:发现类似问题,写了一个简单的基于jQuery的函数来启用/禁用复选框和父跨度
function resetChk(ctl, bEnable)
if (bEnable)
ctl.removeAttr('disabled').parent().removeAttr('disabled');
else
ctl.attr('disabled', true).parent().attr('disabled', true);
【讨论】:
以上是关于为啥 ASP.Net RadioButton 和 CheckBox 在 Span 内呈现?的主要内容,如果未能解决你的问题,请参考以下文章