【问题标题】:Rendered pIxel width data for each character in a browser's font浏览器字体中每个字符的渲染像素宽度数据
【发布时间】:2010-09-14 19:58:51
【问题描述】:

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

a_really_long_string_of_text_like_this_with_no_line_breaks_makes_the_table_unhappy

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

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

您有显示每个字符的像素宽度的数据吗?还是生成它的程序?

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

【问题讨论】:

    标签: javascript jquery html css font-size


    【解决方案1】:

    溢出如何:滚动?

    【讨论】:

      【解决方案2】:

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

      TextMetrics 提供精确的像素测量 用于文本块,以便您可以 确定到底有多高和多宽, 以像素为单位,给定的文本块将 是。

      我确信还有其他可用的库也可以做到这一点。

      【讨论】:

      • 有趣。有人知道 jQuery 等价物吗?
      • XD jquery 已经变得如此无处不在,人们总是首先寻找它。
      • 这不是服务器端的。对于其他搜索,请查看github.com/nodebox/opentype.js,它看起来很有希望。
      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        在服务器端做起来非常非常困难。你永远无法知道用户安装了哪些字体,影响文字显示的因素很多。

        试试这个:

        table-layout: fixed;
        

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

        【讨论】:

        • 这是一个有用的解决方案,因为它不会破坏表格。但它没有显示省略号。
        • 做到这一点真的不容易。我能想到的最好的方法是一个小的 JS 函数,它可以在新元素中呈现省略号,将副本附加到每个单元格,并根据每个单元格的 scrollWidth/clientWidth 显示/隐藏它们。
        • .. 但该解决方案需要将事件附加到 onload、onresize 以及其他任何可能导致表格显示受到影响的事件,这对浏览器来说有点重,所以我真的不推荐它。
        • 好主意。我想我会在 jQuery 中尝试这样的事情。它不需要绑定来调整事件大小,因为表格是固定宽度的。
        【解决方案5】:

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

        它的运行速度比我预期的要快一些。它假定单元格的内容仅为文本 - 任何 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();
              }
        
            }
          });
        
        }
        

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          • 啊 - 我没有考虑字距调整。
          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

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

            -- 但简单的方法是在表格单元格内放置一个块元素:

            <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]

            【讨论】:

              【解决方案9】:

              如果您认为这不适用于 FireFox,为什么不直接使用 CSS?有表格布局的表格:固定,有问题的列有溢出:隐藏;文本溢出:省略号;空白:nowrap。

              【讨论】:

                【解决方案10】:
                http://www.css3.info/preview/text-overflow/
                

                这是css3的新功能。

                【讨论】:

                  【解决方案11】:

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

                  【讨论】:

                    【解决方案12】:

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

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

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

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

                    【讨论】:

                      【解决方案13】:

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

                      更新:我环顾四周,似乎并非所有浏览器都支持 wbr。最值得注意的是,IE8。我自己还没有测试过。也许您可以使用溢出:隐藏作为备份或类似的东西。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2019-05-07
                        • 2021-10-18
                        • 2021-09-12
                        • 1970-01-01
                        • 2011-12-15
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多