5

我看到这个问题已经在 IE9 上被问过了,但是它在 html 表的随机行中添加了额外的列。根本问题似乎是在 IE 10 中修复的 IE 9 错误(但我有很多 IE9 用户)

它指出它通常发生在通过 ajax 构建的表中,但我在输出 html 表的常规页面上看到了这种情况。

有一个解决方法 Javascript 解决方案,但答案假定您正在使用 Javascript(来自 ajax 调用)构建一个表。我正在使用部分视图(或者在某些情况下只是直接在单个页面上呈现常规格式的 html 表)所以我想知道当您只是在上呈现直接 html 时是否有解决方案可以防止在 IE9 上出现此 UI 问题页。

我想避免在我的实际代码中实际上没有空格,因为这将很难维护。

4

3 回答 3

5

我遇到了同样的问题并最终在此页面上寻找解决方案。在我的情况下,问题在于由带有 ASP.Net 4 的 Repeater 控件呈现的 HTML。

我用 Charles 检查了服务器生成的代码,HTML 没有问题。

问题中的最后一句话让我找到了自己的简单解决方案。

我想避免在我的实际代码中实际上没有空格,因为这将很难维护。

我只是在 TR 标记的开头和第一个 TD 标记之间以及每个 TD 和结束的 TR 标记之间添加注释:

<tr><!--
 --><td class="cell">
    Cell 1  
    </td><!--
 --><td class="cell">
    Cell 2  
    </td><!--
 --><td class="cell">
    Cell 3  
    </td><!--
 --><td class="cell">
    Cell 1  
    </td><!--
 --></tr>

这个解决方案意味着我们不必使用扩展,将来阅读或维护代码也不会很困难。

于 2014-03-07T22:48:36.013 回答
2

这个有可能。对于部分视图,它更简单,因为您可以Html.Partial直接捕获输出,在将响应写入输出流之前对其进行修改。

为此,您将创建一个扩展方法,它可能看起来像这样:

public static class HtmlExtensions
{
    public static HtmlString PartialIE9TableFix(this HtmlHelper helper,
        string view, object model = null)
    {
        var partialOutput = helper.Partial(view, model).ToString();
        partialOutput = Regex.Replace(partialOutput, @"/td>\s+<td",
                            "/td><td", RegexOptions.IgnoreCase);

        return MvcHtmlString.Create(partialOutput);
    }
}

如您所见,它Html.Partial直接捕获 的输出,然后对其执行替换。您可以像这样在视图中使用它:

@Html.PartialIE9TableFix("YourPartial")

但是,要为实际视图执行此操作需要更多的工作,并且在使用它时当然要更加小心。为了做到这一点,我们实际上需要在将响应流发送到客户端之前对其进行捕获和修改。

下面IE9TableFixFilter的代码非常基于Minify HTML with .NET MVC ActionFilter的代码。

using System;
using System.IO;
using System.Text;

public class IE9TableFixFilter : Stream
{
    public IE9TableFixFilter(Stream response, Func<string, string> filter)
    {
        this.response = response;
        this.filter = filter;
    }

    public override bool CanRead { get { return true; } }
    public override bool CanSeek { get { return true; } }
    public override bool CanWrite { get { return true; } }
    public override void Flush() { response.Flush(); }
    public override long Length { get { return 0; } }
    public override long Position { get; set; }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return response.Read(buffer, offset, count);
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return response.Seek(offset, origin);
    }

    public override void SetLength(long value)
    {
        response.SetLength(value);
    }

    public override void Close()
    {
        response.Close();
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        //byte[] data = new byte[count];
        //Buffer.BlockCopy(buffer, offset, data, 0, count);
        string s = Encoding.Default.GetString(buffer);

        s = filter(s);

        byte[] outData = Encoding.Default.GetBytes(s);
        response.Write(outData, 0, outData.GetLength(0));
    }

    private Stream response;
    private Func<string, string> filter;
}

这里的大部分代码都是abstractStream. 重要的部分是Write方法中发生了什么。

文章中的版本Write首先复制流的字节而不实际使用它们。如果这是出于某种特定原因,则没有提及,但这对我来说似乎没用,所以我将这些行注释掉了。

接下来,我们需要创建一个简单ActionFilter的应用响应过滤器:

using System.Text.RegularExpressions;
using System.Web.Mvc;

public class IE9TableFixFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var response = filterContext.HttpContext.Response;
        response.Filter = new IE9TableFixFilter(response.Filter,
            s => Regex.Replace(s, @"/td>\s+<td", "/td><td", RegexOptions.IgnoreCase));
    }
}

现在一切都完成了,我强烈建议您不要全局应用此过滤器,而是选择在需要使用它的操作上装饰它。这样做的原因是因为它自然会导致一些性能损失,所以最好明确说明何时真正需要它。使用它时,您将不需要部分扩展方法。因此,只需装饰您的操作即可使用它:

[IE9TableFixFilterAttribute]
public ActionResult Index()
{
    return View();
}

更新

为了使过滤器属性更有效,您实际上可以将其应用于包含用户代理字符串的浏览器MSIE 9.0

public class IE9TableFixFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var request = filterContext.HttpContext.Request;
        var response = filterContext.HttpContext.Response;

        if (request.UserAgent.Contains("MSIE 9.0"))
        {
            response.Filter = new IE9TableFixFilter(response.Filter,
                s => Regex.Replace(s, @"/td>\s+<td", "/td><td", RegexOptions.IgnoreCase));
        }
    }
}
于 2014-01-10T20:31:21.007 回答
0

除了清除空白之外,您还可以尝试以下修复方法之一:

  • CSS:td { white-space: nowrap; }如果适用!

  • 强制您的表格具有固定布局:

<table style="table-layout: fixed" width="600">
  <colgroup>
    <col width="100"><col width="300"><col width="200">
  </colgroup>
  <tr height="20">
    <td>...</td>
    <td>...</td>
    <td>...</td>
  </tr>
</table>
  • 如果您的 Web 应用程序已经支持 IE8,您可以通过以下方式强制 IE9 用户使用 IE8 渲染引擎: <meta http-equiv="X-UA-Compatible" content="IE=8" />
于 2014-01-19T13:19:26.137 回答