渲染时如何从 WebControl 中删除 span 标签

发布于 2024-08-20 06:34:43 字数 137 浏览 3 评论 0原文

当使用 ASP.NET CheckBox (在特殊情况下,继承自 CheckBox)时,它会在复选框输入控件周围呈现一个跨度,此跨度控件会影响 jQuery 脚本。

渲染时可以去掉这个跨度吗?

When using an ASP.NET CheckBox (and in out case, inherited from a CheckBox) it renders a span around the checkbox input control, this span control is affecting jQuery scripts.

Is it possible to remove this span when rendering?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

天冷不及心凉 2024-08-27 06:34:43

发现这个有用的提示:

在代码隐藏中,使用 InputAttributes 而不是 Attributes。

例如,键入此:

chk.InputAttributes.Add("onchange", "updateFields()")

而不是此:

chk.Attributes.Add("onchange", "updateFields()")

或而不是内联声明:

<asp:CheckBox ID="chk" runat="server" onchange="updateFields()" />

最后两个将导致换行跨度。

Found this useful tip:

In Code Behind, use InputAttributes instead of Attributes.

For Example, type this:

chk.InputAttributes.Add("onchange", "updateFields()")

instead of this:

chk.Attributes.Add("onchange", "updateFields()")

or instead of inline declarations:

<asp:CheckBox ID="chk" runat="server" onchange="updateFields()" />

The last two will cause the wrapping span.

靖瑶 2024-08-27 06:34:43

我刚刚在测试页上尝试过这个,但我没有得到我的 CheckBox 控件...您确定是 CheckBox 正在渲染它吗?是有条件的吗?

更新:好的,这似乎取决于 CheckBox 是否具有额外的属性,包括 CssClass 设置...或“禁用”属性。

I just tried this on a test page and I'm not getting the around my CheckBox controls... are you sure it's the CheckBox that's rendering this? Is it conditional?

UPDATE: OK, it appears to be conditional on whether or not the CheckBox has extra attributes, including a CssClass setting... or a "disabled" attribute.

々眼睛长脚气 2024-08-27 06:34:43

我不知道这是否适用于这个特定的例子。但是,如果您制作自己的 WebControl 并且您永远不希望它在自身周围呈现跨度,您可以像这样重写 Controls 渲染方法:

public class MyWebControl : WebControl
{

  /* Your code 
             between here */

  protected override void Render(HtmlTextWriter writer)
  {
    RenderContents (writer);
  }
}

我猜您可以将相同的内容添加到继承的 CheckBox...类似这样的内容

public class MyCheckBox : CheckBox 
{

  /* Your code 
             between here */

  protected override void Render(HtmlTextWriter writer)
  {
    RenderContents (writer);
  }
}

:解决方案在这里有更好的解释:
http://www.marten-online.com/net /stripping-span-tag-from-webcontrol.html

I don't know if this will work on this particular example. But if you make your own WebControl and you never want it to render spans around itself you can override the Controls render method like this:

public class MyWebControl : WebControl
{

  /* Your code 
             between here */

  protected override void Render(HtmlTextWriter writer)
  {
    RenderContents (writer);
  }
}

I guess that you could add the same to an inherited CheckBox... something like this:

public class MyCheckBox : CheckBox 
{

  /* Your code 
             between here */

  protected override void Render(HtmlTextWriter writer)
  {
    RenderContents (writer);
  }
}

The basic problem with the solution is better explained here:
http://www.marten-online.com/net/stripping-span-tag-from-webcontrol.html

树深时见影 2024-08-27 06:34:43

我花了过去 3 个小时的时间来解决这个问题。

结果如下:

using System.Web.UI;
using System.Web.UI.WebControls;

/// <summary>
/// Represents a custom checkbox web control.
/// Prevents itself to be wrapped into a <span> tag when disabled.
/// </summary>
public class CustomCheckBox : CheckBox
{
    /// <summary>
    /// Renders the control to the specified HTML writer.
    /// </summary>
    /// <param name="writer">The HtmlTextWriter object that receives the control content.</param>
    protected override void Render(HtmlTextWriter writer)
    {
        // Use custom writer
        writer = new HtmlTextWriterNoSpan(writer);

        // Call base class
        base.Render(writer);
    }
}

除了自定义控件之外,您还需要一个自定义 HtmlTextWriter:

using System.IO;
using System.Web.UI;

/// <summary>
/// Represents a custom HtmlTextWriter that displays no span tag.
/// </summary>
public class HtmlTextWriterNoSpan : HtmlTextWriter
{
    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="textWriter">Text writer.</param>
    public HtmlTextWriterNoSpan(TextWriter textWriter)
        : base(textWriter)
    { }

    /// <summary>
    /// Determines whether the specified markup element will be rendered to the requesting page.
    /// </summary>
    /// <param name="name">Name.</param>
    /// <param name="key">Tag key.</param>
    /// <returns>True if the markup element should be rendered, false otherwise.</returns>
    protected override bool OnTagRender(string name, HtmlTextWriterTag key)
    {
        // Do not render <span> tags
        if (key == HtmlTextWriterTag.Span)
            return false;

        // Otherwise, call the base class (always true)
        return base.OnTagRender(name, key);
    }
}

仅供参考,使用:

checkbox.InputAttributes.Add("disabled", "disabled");

具有相同的效果,但是:

  1. 它不如 checkbox.Enalbed = false; 方便;
  2. 当复选框位于 ListView 中时,回发后该属性将被删除。

I spent the last 3 hours pulling my hair to find a solution at this problem.

Here is what came out:

using System.Web.UI;
using System.Web.UI.WebControls;

/// <summary>
/// Represents a custom checkbox web control.
/// Prevents itself to be wrapped into a <span> tag when disabled.
/// </summary>
public class CustomCheckBox : CheckBox
{
    /// <summary>
    /// Renders the control to the specified HTML writer.
    /// </summary>
    /// <param name="writer">The HtmlTextWriter object that receives the control content.</param>
    protected override void Render(HtmlTextWriter writer)
    {
        // Use custom writer
        writer = new HtmlTextWriterNoSpan(writer);

        // Call base class
        base.Render(writer);
    }
}

Along with the custom control, you'll need a custom HtmlTextWriter:

using System.IO;
using System.Web.UI;

/// <summary>
/// Represents a custom HtmlTextWriter that displays no span tag.
/// </summary>
public class HtmlTextWriterNoSpan : HtmlTextWriter
{
    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="textWriter">Text writer.</param>
    public HtmlTextWriterNoSpan(TextWriter textWriter)
        : base(textWriter)
    { }

    /// <summary>
    /// Determines whether the specified markup element will be rendered to the requesting page.
    /// </summary>
    /// <param name="name">Name.</param>
    /// <param name="key">Tag key.</param>
    /// <returns>True if the markup element should be rendered, false otherwise.</returns>
    protected override bool OnTagRender(string name, HtmlTextWriterTag key)
    {
        // Do not render <span> tags
        if (key == HtmlTextWriterTag.Span)
            return false;

        // Otherwise, call the base class (always true)
        return base.OnTagRender(name, key);
    }
}

Just FYI, using:

checkbox.InputAttributes.Add("disabled", "disabled");

has the same effect but:

  1. It's not as convenient as checkbox.Enalbed = false;
  2. The attribute is removed after a postback when the checkbox is in a ListView.
明月松间行 2024-08-27 06:34:43

使用 Jquery

<script>
        $(".selector input").unwrap().addClass("cssclass");
</script>

Using Jquery

<script>
        $(".selector input").unwrap().addClass("cssclass");
</script>
空城旧梦 2024-08-27 06:34:43
    protected override HtmlTextWriterTag TagKey
    {
        get
        {              
            return HtmlTextWriterTag.Div;
        }
    }

应该做

    protected override HtmlTextWriterTag TagKey
    {
        get
        {              
            return HtmlTextWriterTag.Div;
        }
    }

should do

凑诗 2024-08-27 06:34:43

如果您不需要标签,可以直接使用输入/复选框控件,或者可以自己放置一个:

<input type="checkbox" id="CheckBox1" runat="server" />
<label for="CheckBox1">My Label</label>

CSS 适配器可能能够删除复选框/标签周围的跨度,但我还没有看到用于此目的的跨度。

You can use the input/checkbox control directly if you don't need a label, or can put one yourself:

<input type="checkbox" id="CheckBox1" runat="server" />
<label for="CheckBox1">My Label</label>

A CSS Adapter may be able to remove the span around the checkbox/label, but I haven't seen one for that purpose.

〃温暖了心ぐ 2024-08-27 06:34:43

为什么不使用 .remove 和 jquery 删除跨度?

Why don't you remove the span using .remove with jquery ?

人心善变 2024-08-27 06:34:43

您可以使用文字控件来代替吗?这两种选择之间有很大的区别:

<p>12345<asp:Label ID="lblMiddle" runat="server" Text="6"></asp:Label>7890</p>
<p>12345<asp:Literal ID="ltlMiddle" runat="server" Text="6"></asp:Literal>7890</p>

Can you use a literal control instead? There's a big difference between these two alternatives:

<p>12345<asp:Label ID="lblMiddle" runat="server" Text="6"></asp:Label>7890</p>
<p>12345<asp:Literal ID="ltlMiddle" runat="server" Text="6"></asp:Literal>7890</p>
太阳哥哥 2024-08-27 06:34:43

我发现通过实现如下所示的构造函数,您可以为控件指定容器标记。

public MyCustomControl() : base(HtmlTextWriterTag.Div)
{
}

您可以将 HtmlTextWriterTag 替换为任何可用选项,例如上例中的 Div。默认值为 Span

I've found that by implementing a constructor like the one below, you can specify the container tag for your control.

public MyCustomControl() : base(HtmlTextWriterTag.Div)
{
}

You can replace the HtmlTextWriterTag with any of the aviable options, such as Div in the example above. The default is Span.

又怨 2024-08-27 06:34:43
$(document).ready(function() {
  /* remove the relative spam involving inputs disabled */
  $('input[type="checkbox"]').parent('.aspNetDisabled').each(function() {
    var $this = $(this);
    var cssClass = $this.attr('class');
    $this.children('input[type="checkbox"]').addClass(cssClass).unwrap().parent('label[for],span').first().addClass('css-input-disabled');
  });
});
/* CSS Example */
.css-input {
  position: relative;
  display: inline-block;
  margin: 2px 0;
  font-weight: 400;
  cursor: pointer;
}
.css-input input {
  position: absolute;
  opacity: 0;
}
.css-input input:focus + span {
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
}
.css-input input + span {
  position: relative;
  display: inline-block;
  margin-top: -2px;
  margin-right: 3px;
  vertical-align: middle;
}
.css-input input + span:after {
  position: absolute;
  content: "";
}
.css-input-disabled {
  opacity: .5;
  cursor: not-allowed;
}
.css-checkbox {
  margin: 7px 0;
}
.css-checkbox input + span {
  width: 20px;
  height: 20px;
  background-color: #fff;
  border: 1px solid #ddd;
  -webkit-transition: background-color 0.2s;
  transition: background-color 0.2s;
}
.css-checkbox input + span:after {
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  font-family: "FontAwesome";
  font-size: 10px;
  color: #fff;
  line-height: 18px;
  content: "\f00c";
  text-align: center;
}
.css-checkbox:hover input + span {
  border-color: #ccc;
}
.css-checkbox-primary input:checked + span {
  background-color: #5c90d2;
  border-color: #5c90d2;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- Generate from asp.net -->
<label for="CheckBox1" id="Label4" class="css-input css-checkbox css-checkbox-primary">
  <span class="aspNetDisabled">
    <input id="CheckBox1" 
           type="checkbox" 
           checked="checked" 
           disabled="disabled">
  </span>
  <span></span>Disabled
</label>

$(document).ready(function() {
  /* remove the relative spam involving inputs disabled */
  $('input[type="checkbox"]').parent('.aspNetDisabled').each(function() {
    var $this = $(this);
    var cssClass = $this.attr('class');
    $this.children('input[type="checkbox"]').addClass(cssClass).unwrap().parent('label[for],span').first().addClass('css-input-disabled');
  });
});
/* CSS Example */
.css-input {
  position: relative;
  display: inline-block;
  margin: 2px 0;
  font-weight: 400;
  cursor: pointer;
}
.css-input input {
  position: absolute;
  opacity: 0;
}
.css-input input:focus + span {
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
}
.css-input input + span {
  position: relative;
  display: inline-block;
  margin-top: -2px;
  margin-right: 3px;
  vertical-align: middle;
}
.css-input input + span:after {
  position: absolute;
  content: "";
}
.css-input-disabled {
  opacity: .5;
  cursor: not-allowed;
}
.css-checkbox {
  margin: 7px 0;
}
.css-checkbox input + span {
  width: 20px;
  height: 20px;
  background-color: #fff;
  border: 1px solid #ddd;
  -webkit-transition: background-color 0.2s;
  transition: background-color 0.2s;
}
.css-checkbox input + span:after {
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  font-family: "FontAwesome";
  font-size: 10px;
  color: #fff;
  line-height: 18px;
  content: "\f00c";
  text-align: center;
}
.css-checkbox:hover input + span {
  border-color: #ccc;
}
.css-checkbox-primary input:checked + span {
  background-color: #5c90d2;
  border-color: #5c90d2;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- Generate from asp.net -->
<label for="CheckBox1" id="Label4" class="css-input css-checkbox css-checkbox-primary">
  <span class="aspNetDisabled">
    <input id="CheckBox1" 
           type="checkbox" 
           checked="checked" 
           disabled="disabled">
  </span>
  <span></span>Disabled
</label>

梦幻之岛 2024-08-27 06:34:43

尝试向您的类添加一个如下所示的构造函数:

public MyControl() : base() 
{
}

如果您注意到,控件将默认呈现为跨度,因为这就是“WebControl”使用的内容(如果您使用 Reflector):

protected WebControl() : this(HtmlTextWriterTag.Span) { }

参考:
http://aspnetresources.com/blog/stripping_span_from_webcontrol

Try adding a constructor to your class that looks like this:

public MyControl() : base() 
{
}

If you notice, controls will render as spans as default since that's what the "WebControl" uses (if you use Reflector) :

protected WebControl() : this(HtmlTextWriterTag.Span) { }

Reference:
http://aspnetresources.com/blog/stripping_span_from_webcontrol

第七度阳光i 2024-08-27 06:34:43

我想知道,没有人提到这一点有什么原因吗:

public MyControl() : base(string.Empty)

我读到了这个http://aspnetresources.com/blog/stripping_span_from_webcontrol< /a> flaviotsf 提到的

i wonder, is there a reason no1 mentioned this:

public MyControl() : base(string.Empty)

i got this reading http://aspnetresources.com/blog/stripping_span_from_webcontrol that flaviotsf mentioned

她如夕阳 2024-08-27 06:34:43
                <div class="onoffswitch">
                     <asp:CheckBox ID="example1" runat="server" AutoPostBack="true" OnCheckedChanged="chkWifiRequired_CheckedChanged" CssClass="aspNetDisabled onoffswitch-checkbox"/>
                    <label class="onoffswitch-label" for='<%= example1.ClientID.ToString() %>'>
                        <span class="onoffswitch-inner"></span>
                        <span class="onoffswitch-switch"></span>
                    </label>
                </div>
            /* remove the relative spam involving inputs disabled */
            $('input[name=""]').parent('.aspNetDisabled').each(function () {
                var $this = $(this);
                var cssClass = "onoffswitch-checkbox";
                $('input[name=""]').addClass(cssClass).unwrap().parent('label[for],span').first().addClass('onoffswitch-checkbox');
            });

这将允许您正常使用该复选框,仍然让它调用服务器端代码,并使用引导程序中的切换。 (我使用的是 Inspina 主题,但其他切换的格式应该相同)

                <div class="onoffswitch">
                     <asp:CheckBox ID="example1" runat="server" AutoPostBack="true" OnCheckedChanged="chkWifiRequired_CheckedChanged" CssClass="aspNetDisabled onoffswitch-checkbox"/>
                    <label class="onoffswitch-label" for='<%= example1.ClientID.ToString() %>'>
                        <span class="onoffswitch-inner"></span>
                        <span class="onoffswitch-switch"></span>
                    </label>
                </div>
            /* remove the relative spam involving inputs disabled */
            $('input[name=""]').parent('.aspNetDisabled').each(function () {
                var $this = $(this);
                var cssClass = "onoffswitch-checkbox";
                $('input[name=""]').addClass(cssClass).unwrap().parent('label[for],span').first().addClass('onoffswitch-checkbox');
            });

This will allow you to use the check box normally, still have it call server side code, and use the toggle from bootstrap. (I'm using the Inspina theme but it should be the same format for other toggles)

深居我梦 2024-08-27 06:34:43

我刚刚遇到这个问题并使用了乔恩的答案,这很好而且有效。缺点是您的类是在代码隐藏中定义的,而不是在标记中定义的。

因此,我接受了答案,并采用了一种编程方式来检索控件的所有属性,将它们复制到 InputAttributes 并从属性中删除这些复制的属性。

请注意,虽然它扩展自 RadioButton,但您可以使用该方法扩展任何控件,例如标签或复选框。

using System.Web.UI;
using System.Web.UI.WebControls;

namespace Hidistro.UI.Common.Controls
{
    /// <summary>
    /// Just like a normal RadioButton, except that the wrapped span is disabled.
    /// </summary>
    public class CleanRadioButton : RadioButton
    {
        protected override void Render(HtmlTextWriter writer)
        {
            List<string> keysToRemove = new List<string>();

            foreach (object key in Attributes.Keys)
            {
                string keyString = (string)key;
                InputAttributes.Add(keyString, Attributes[keyString]);
                keysToRemove.Add(keyString);
            }

            foreach (string key in keysToRemove)
                Attributes.Remove(key);

            base.Render(writer);
        }
    }
}

这样,您只需执行以下操作,它将输出不带跨度的标签。

<namespace:CleanRadioButton class="class1" />
<namespace:CleanRadioButton class="class2" />

HTML 输出:
(注意“生成”是自动生成的)

<input id="generated" type="radio" name="generated" value="generated" class="class1">
<input id="generated" type="radio" name="generated" value="generated" class="class2">

I just had this issue and used Jon's answer, which is good and it works. The downside is that your class is defined within the codebehind and not your markup.

So I took the answer and made a progamatic way to retrieve all attributes for the control, copy them to InputAttributes and remove those copied attributes from attributes.

Note that while this extends from RadioButton, you could use the method to extend any control, such as labels or checkboxes.

using System.Web.UI;
using System.Web.UI.WebControls;

namespace Hidistro.UI.Common.Controls
{
    /// <summary>
    /// Just like a normal RadioButton, except that the wrapped span is disabled.
    /// </summary>
    public class CleanRadioButton : RadioButton
    {
        protected override void Render(HtmlTextWriter writer)
        {
            List<string> keysToRemove = new List<string>();

            foreach (object key in Attributes.Keys)
            {
                string keyString = (string)key;
                InputAttributes.Add(keyString, Attributes[keyString]);
                keysToRemove.Add(keyString);
            }

            foreach (string key in keysToRemove)
                Attributes.Remove(key);

            base.Render(writer);
        }
    }
}

This way, all you need to do is the following, and it will output tags without the span.

<namespace:CleanRadioButton class="class1" />
<namespace:CleanRadioButton class="class2" />

HTML output:
(note that "generated" is autogenerated)

<input id="generated" type="radio" name="generated" value="generated" class="class1">
<input id="generated" type="radio" name="generated" value="generated" class="class2">
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文