通过WebApp确定打印字符串的宽度

时间:2020-03-05 18:44:49  来源:igfitidea点击:

在我的(PHP)网络应用程序中,我拥有网站的一部分,其中保留了近期搜索的历史记录。最新查询显示在边栏中。如果查询文本太长,我将其截断并显示省略号。例如:"我很长的查询是..."

目前,我截断了一定数量的字符。由于字体不是单型的,所以对所有I的查询比对所有W的查询要狭窄。我希望它们在省略号之前都具有相同的宽度。有没有办法得到结果字符串的近似宽度,以便任何给定字符串的省略号从一开始就以大约相同的像素数出现? CSS有办法吗?有PHP吗?用JavaScript可以更好地处理吗?

解决方案

回答

Does CSS have a way?

Does PHP?

--

为此,我们必须获取每个字符的字体指标,并将其应用于字符串中的所有字母。尽管我们可以通过在服务器上使用诸如ImageMagick之类的图形/渲染库来执行此操作,但它实际上并不会起作用,因为在不同操作系统上,不同的浏览器会呈现不同的字体。

即使它确实起作用,我们也不想这样做,因为它也将永远需要渲染。服务器每秒可以推送1页(如果有的话),而不是数千页。

如果我们可以在没有尾随...的情况下生存,那么可以使用div标签和CSSoverflow:hidden很好地伪造它,如下所示:

.line_of_text {
    height:1.3em;
    line-height:1.3em;
    overflow:hidden;
}

<div class="line_of_text"> Some long text which will arbitrarily be cut off at whatever word fits best</div>

回答

这是另一种做法,我们不必没有省略号就可以生活!

<html>
<head>

<style>
div.sidebox {
    width: 25%;
}

div.sidebox div.qrytxt {
    height: 1em;
    line-height: 1em;
    overflow: hidden;
}

div.sidebox div.qrytxt span.ellipsis {
    float: right;
}
</style>

</head>

<body>

<div class="sidebox">
    <div class="qrytxt">
        <span class="ellipsis">&hellip;</span>
        Some long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
    </div>
    <div class="qrytxt">
        <span class="ellipsis">&hellip;</span>
        Some more long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
    </div>
    <div class="qrytxt">
        <span class="ellipsis">&hellip;</span>
        Short text. Fail!
    </div>
</body>

</html>

这有一个缺陷,如果文本足够短以至于无法完全显示,则椭圆也将仍然显示。

[编辑:2009年6月26日]

在Power-Coder的建议下,我对此进行了一些修改。实际上只有两处更改,即.qrytxtDIV上的doctype(见下面的注释)和display:inline-block属性的添加。这是现在的样子...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <style>
        div.sidebox 
        {
            width: 25%;
        }

        div.sidebox div.qrytxt
        {
            height: 1em;
            line-height: 1em;
            overflow: hidden;
            display: inline-block;
        }

        div.sidebox div.qrytxt span.ellipsis
        {
            float: right;
        }
</style>
</head>

<body>
    <div class="sidebox">
        <div class="qrytxt">
            <span class="ellipsis">&hellip;</span>
            Some long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
        </div>

        <div class="qrytxt">
            <span class="ellipsis">&hellip;</span>
            Some more long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
        </div>

        <div class="qrytxt">
            <span class="ellipsis">&hellip;</span>
            Short text. FTW
        </div>
    </div>
</body>
</html>

笔记:

  • 在IE 8.0,Opera 9,FF 3中查看
  • IE需要doctype才能使display:inline-block正常工作。
  • 如果.qrytxtDIV的溢出发生在一个长字上,则省略号和最后一个可见字之间会有很大的距离。我们可以通过查看示例并以较小的增量调整浏览器的宽度来查看此内容。 (这可能也存在于原始示例中,那时我可能没有注意到它)

同样,这是一个不完美的纯CSS解决方案。 Javascript可能是唯一可以完美实现效果的东西。

[编辑:2009年6月27日]

这是使用浏览器特定扩展的另一种选择。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>
<head>
    <style>
        div.sidebox 
        {
            width: 26%;
        }

        div.sidebox div.qrytxt
        {
            height: 1em;
            line-height: 1em;
            overflow: hidden;
            text-overflow:ellipsis;
            -o-text-overflow:ellipsis;
            -ms-text-overflow:ellipsis;
            -moz-binding:url(ellipsis-xbl.xml#ellipsis);
            white-space:nowrap;
        }
    </style>
</head>

<body>
    <div class="sidebox">
        <div class="qrytxt">
            Some long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
        </div>

        <div class="qrytxt">
            Some more long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
        </div>

        <div class="qrytxt">
            Short text. FTW
        </div>
    </div>
</body>
</html>

请注意,为了使上述示例生效,必须创建-moz-binding规则ellipsis-xbl.xml引用的xml文件。它应包含以下xml:

<?xml version="1.0" encoding="UTF-8"?>
  <bindings xmlns="http://www.mozilla.org/xbl" xmlns:xbl="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <binding id="ellipsis">
      <content>
        <xul:window>
          <xul:description crop="end" xbl:inherits="value=xbl:text"><children/></xul:description>
        </xul:window>
      </content>
    </binding>
  </bindings>

回答

罗伯特

如果我们将椭圆放在z-index较低的div中,这样当椭圆向左移动(对于较短的行)时,背景图像或者其他东西会掩盖该怎么办?

我知道这很hacky,但是值得一试吗?

编辑另一个想法:使用javascript确定包含椭圆的div的位置,如果没有完全正确地将其隐藏,将其隐藏吗?

回答

我们也可以很容易地使用一些javascript:

document.getElementByID("qrytxt").offsetWidth;

将为我们提供元素的宽度(以像素为单位),甚至可以在IE6中使用。如果在每个查询的末尾添加一个包含椭圆的跨度,则可以在JavaScript中使用一些CSS操作对逻辑进行简单的测试,以根据需要隐藏/显示它们。

回答

由于即使有一个用于测量字体的函数http://www.php.net/imageftbbox,也应该完全不考虑PHP,因为PHP无法知道访问者是否具有最小访问量字体大小设置大于预期的字体大小。