为浏览器字体中的每个字符渲染pIxel宽度数据

时间:2008-10-02 14:49:47

标签: javascript jquery html css font-size

我有一个表格列需要限制在一定的宽度 - 比如100像素。有时,该列中的文本比此更宽,并且不包含空格。例如:

a_really_long_string_of_text_like_this_with_no_line_breaks_makes_the_table_unhappy

我想计算文本服务器端的宽度,并在正确的字符数后添加省略号。问题是我没有关于文本渲染大小的数据。

例如,假设浏览器是Firefox 3,字体是12px Arial。字母“a”的宽度,字母“b”的宽度等等是什么?

你有数据显示每个角色的像素宽度吗?还是一个生成它的程序?

我认为一个聪明的一次性JavaScript脚本可以做到这一点。但如果其他人已经这样做了,我不想花时间重新发明轮子。我肯定不是第一个反对这个问题的人。

13 个答案:

答案 0 :(得分:3)

溢出怎么样?滚动?

答案 1 :(得分:3)

Ext JS有一个模块可以做到这一点

  

TextMetrics   提供精确的像素测量   对于文本块,你可以   确切地确定了多高和多宽,   以像素为单位,给定的文本块将   是。

我确信还有其他可用的库也可以。

答案 2 :(得分:2)

这不仅不可能做服务器端,也没有意义。您不知道客户端将使用哪种浏览器,并且您不知道客户端上的哪些字体设置将覆盖您为一段HTML分配的任何样式信息。您可能认为您在样式属性中使用绝对定位像素,但客户端可能只是忽略这些像素或使用某些插件来缩放所有内容,因为客户端使用高dpi屏幕。

使用固定宽度通常是一个坏主意。

答案 3 :(得分:1)

服务器端很难做到。您永远不会知道用户安装了哪些字体,并且有很多因素会影响文本的显示。

请改为尝试:

table-layout: fixed;

这将确保表格永远不会超过您指定的尺寸。

答案 4 :(得分:1)

这是我提出的客户端解决方案。它非常特定于我的应用程序,但我在这里分享它以防其他人遇到同样的问题。

它比我预期的要快一点。并且它假定单元格的内容仅为文本 - 任何HTML格式都将在缩短过程中被删除。

它需要jQuery。

function fixFatColumns() {
  $('table#MyTable td').each(function() {
    var defined_width = $(this).attr('width');
    if (defined_width) {
      var actual_width = $(this).width();
      var contents = $(this).html();
      if (contents.length) {
        var working_div = $('#ATempDiv');
        if (working_div.is('*')) {
          working_div.html(contents);
        } else {
          $('body').append('<div id="ATempDiv" style="position:absolute;top:-100px;left:-500px;font-size:13px;font-family:Arial">'+contents+'</div>');
          working_div = $('#ATempDiv');
        }

        if (working_div.width() > defined_width) {
          contents = working_div.text();
          working_div.text(contents);
          while (working_div.width() + 8 > defined_width) {
            // shorten the contents of the columns
            var working_text = working_div.text();
            if (working_text.length > 1) working_text = working_text.substr(0,working_text.length-1);
            working_div.text(working_text);
          }
          $(this).html(working_text+'...')
        }

        working_div.empty();
      }

    }
  });

}

答案 5 :(得分:0)

这在服务器端基本上是不可能的。除了安装了不同字体的人的问题之外,你还有字距调整(字母“f”将占用不同的空间,具体取决于它旁边的内容)和字体渲染选项(是否为cleartype?“大字体“?)。

答案 6 :(得分:0)

你可以将文本放入一个看不见的跨度并读取宽度,但基本上这看起来像是有人试图破坏你的网站,因此我建议禁止使用长度超过某个长度的帖子,例如30个字符没有空格(允许链接更长! - )

- 但简单的方法是将一个块元素放在table-cell中:

<td><div style="width:100px;overflow:hidden">a_really_long_string_of_text_like_this_with_no_line_breaks_makes_the_ta ... </div></td>

这将有效地阻止表格混乱!o]

答案 7 :(得分:0)

没有什么可以在服务器端进行计算。您需要使用的只是浏览器标识字符串,它可能会或可能不会准确地告诉您用户的操作系统和浏览器。您还可以“询问”(通过字体标记或CSS)某个字体用于显示文本,但不保证用户已安装该字体。除此之外,用户可以在操作系统级别具有不同的DPI设置,或者可以通过浏览器缩放功能使文本更大或更小,或者可以完全使用他们自己的样式表。

答案 8 :(得分:0)

如果您对FireFox不起作用,那么为什么不使用CSS呢?有表格布局的表:固定,有问题的列有溢出:隐藏;文本溢出:省略号;空白:NOWRAP

答案 9 :(得分:0)

http://www.css3.info/preview/text-overflow/

这是css3的新功能。

答案 10 :(得分:0)

某些用户的默认字体设置较大或较小。您无法在服务器上执行此操作。您只能在浏览器呈现页面后进行测量。

答案 11 :(得分:0)

由于可以在浏览器端轻松更改字体大小,因此服务器端计算很容易变得无效。

快速客户端修复方法是使用溢出属性设置单元格的样式:

td
{
    overflow: scroll; /* or overflow: hidden;  etc. */
}

更好的选择是截断你的字符串服务器端并提供一个简单的javascript工具提示,可以显示更长的版本。 “展开”按钮也可能有助于在叠加div中显示结果。

答案 12 :(得分:0)

你想要的是&lt; wbr&gt;标签。这是一个特殊的HTML标记,它告诉浏览器如果需要换行,可以在这里断言。我不会将文本注入到持久存储的文本中,因为这样您就可以将数据与显示数据的位置/方式相结合。但是,将标记服务器端注入以视图为中心的代码(如使用JSP标记或可能在控制器中)是完全可以接受的。我就是这样做的。只需使用一些正则表达式来查找长于X个字符的单词,并将每个X字符的这个标记注入到这样的单词中。

更新:我正在做一些环顾四周,看起来所有浏览器都不支持wbr。最值得注意的是,IE8。我自己没有测试过这个。也许您可以使用overflow:hidden作为备份或类似的东西。