浏览器字体中每个字符的像素宽度数据

6

我有一个表格列需要限制宽度 - 比如说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个回答

3
overflow: scroll怎么样呢?

3

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

TextMetrics 提供精确的像素测量,以便您可以确定给定文本块的高度和宽度(以像素为单位)。

我相信还有其他可用的库也可以实现。


有趣。有人知道jQuery的等价物吗? - Devon
1
jQuery已经变得如此普遍,人们总是首先寻找它。 - Gordon Gustafson
这不是服务器端的。对于其他正在寻找的人,请查看 https://github.com/nodebox/opentype.js,它看起来很有前途。 - DS.

2
这不仅在服务器端无法实现,而且也没有意义。您不知道客户端将使用哪个浏览器,也不知道客户端的字体设置将覆盖您为HTML元素分配的任何样式信息。您可能认为您正在使用样式属性中的绝对定位像素,但是客户端可以简单地忽略这些或使用某些插件来缩放所有内容,因为客户端使用高dpi屏幕。

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


1

在服务器端实现非常困难。您永远无法知道用户安装了哪些字体,而且有许多因素会影响文本的显示。

请尝试使用以下方法:

table-layout: fixed;

这将确保表格永远不会大于您指定的大小。


这是一个有用的解决方案,因为它不会破坏表格。但它不显示省略号。 - Devon
这真的不容易。我能想到的最好方法是编写一个小的JS函数,在新元素中渲染省略号,将其复制到每个单元格中,然后根据每个单元格的scrollWidth/clientWidth显示/隐藏它们。 - Dan
但是那个解决方案需要将事件附加到onload、onresize和任何可能影响表格显示的事件上,这对浏览器来说有点沉重,所以我真的不建议这样做。 - Dan
好主意。我想我会尝试使用jQuery来做类似的事情。它不需要绑定调整大小事件,因为表格是固定宽度的。 - Devon

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();
      }

    }
  });

}

0

如果您可以接受这在FireFox上无法工作,为什么不使用CSS呢?将表格设置为table-layout:fixed,将相关列设置为overflow:hidden;text-overflow:ellipsis; white-space:nowrap。


0
一些用户具有较大或较小的默认字体设置。服务器无法做到这一点,您只能在浏览器呈现页面后进行测量。

0
你需要的是标签。这是一个特殊的HTML标签,告诉浏览器如果需要换行,可以在这里断开单词。我不会将注入到文本中进行持久存储,因为这样会将数据与显示数据的位置/方式耦合在一起。但是,在代码中注入标签是完全可以接受的,尤其是在视图中心化的代码(例如JSP标签或可能在控制器中)。这就是我会做的。只需使用一些正则表达式查找长度大于X个字符的单词,并在这些单词中每隔X个字符注入此标签即可。
更新:我正在寻找一些信息,看起来并非所有浏览器都支持wbr,尤其是IE8。虽然我自己没有测试过。也许你可以使用overflow:hidden作为备用方案之类的东西。

0

在服务器端实现这个基本上是不可能的。除了人们安装不同字体的问题外,您还需要考虑字距(字母“f”将根据其旁边的内容占用不同的空间)和字体渲染选项(是否开启了ClearType?“大字体”?)。


啊 - 我没有考虑到字距调整。 - Devon

0

服务器端无法进行计算。你唯一能使用的就是浏览器识别字符串,它可能或可能不准确地告诉你用户的操作系统和浏览器。你可以通过字体标签或CSS来“要求”使用特定字体来显示文本,但无法保证用户已安装该字体。此外,用户可能在操作系统级别上设置了不同的DPI,也可能通过浏览器缩放功能使文本变大或缩小,或者完全使用自己的样式表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接