我怎样才能模仿文本溢出:Firefox中的省略号?

时间:2009-11-30 15:10:15

标签: javascript html string truncation css3

我在div中包含一些动态文本,该文本设置为用户在文本框字段中输入的内容。如果文本不适合div,那么它现在只是在边缘切断,并且所有超出边框的文本都不可见。我想截断文本,使其适合框内,并在末尾附加省略号(...)。例如:

|----div width------|
 Here is some sample text that is too long.
 Here is some sam...

显然在示例中它很容易,因为代码标签使用固定宽度的字体,因此它就像计算字符一样简单。我有一个可变宽度的字体,所以如果他们输入“WWWWWWWWWWW”,它将填充比“................”更少的字符。

最好的方法是什么?我找到了一个潜在的解决方案,可以在这里简单地找到文本的实际像素宽度:http://www.codingforums.com/archive/index.php/t-100367.html

但即使使用这样的方法,实现省略号也有点尴尬。因此,如果它是20个字符并且我发现它不适合,我将不得不截断为19,添加省略号,然后检查它是否再次适合。然后截断为18(加上省略号)并再试一次。然后再次。再次......直到它适合。还有更好的方法吗?

编辑:我根据答案确定了我最初的方法是最好的,除了我试图通过不创建一个单独的td元素来改进上面链接中的解决方案,这只是为了测量,这感觉就像一个黑客。 / p>

这是我的代码:

<div id="tab" class="tab">
    <div id="tabTitle" class="tabTitle">
        <div class="line1">user-supplied text will be put here</div>
        <div class="line2">more user-supplied text will be put here</div>
    </div>
</div>

风格:

.tab {
padding: 10px 5px 0px 10px;
margin-right: 1px;
float: left;
width: 136px;
height: 49px;
background-image: url(../images/example.gif);
background-position: left top;
background-repeat: no-repeat;
}    

.tab .tabTitle {
    height: 30px;
width: 122px;
    overflow: hidden;
    text-overflow: ellipsis;
font-size: 12px;
font-weight: bold;
color: #8B8B8B;
}

.tab .tabTitle .line1, .tab .tabTitle .line2 {
    display:inline;
    width:auto;
}

以及修剪并添加省略号的javascript:

function addOverflowEllipsis( containerElement, maxWidth )
{
    var contents = containerElement.innerHTML;
    var pixelWidth = containerElement.offsetWidth;
    if(pixelWidth > maxWidth)
    {
        contents = contents + "…"; // ellipsis character, not "..." but "…"
    }
    while(pixelWidth > maxWidth)
    {
        contents = contents.substring(0,(contents.length - 2)) + "…";
        containerElement.innerHTML = contents;
        pixelWidth = containerElement.offsetWidth;
    }
}

“line1”和“line2”div传递给函数。它适用于单字输入,例如“WWWWWWWWWWWWWWWWW”,但不能用于多字输入“WWWWW WWWWW WWWWW”,因为它只是添加换行符并将文本测量为“WWWWW”的宽度。

有没有办法解决这个问题,而无需将文本复制到隐藏的测量元素中?某种方法来设置行div的样式,以便它们不包装文本?

13 个答案:

答案 0 :(得分:11)

  

设置行div的样式以便它们不包装文本的某种方式?

你有white-space: nowrap。是的,这也适用于古老的浏览器。

答案 1 :(得分:5)

此问题也必须适用于Firefox。

HTML

<div class="ellipsis">Here goes too long text and when it is takes more than 200px in "end" of the text appears "..."</div>

CSS

.ellipsis{
width:200px;
text-overflow:ellipsis;
-o-text-overflow:ellipsis;
-moz-binding:url('bindings.xml#ellipsis');//issue for Firefox
}

bindings.xml

<bindings xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="none">
    <content><children/></content>
</binding>
<binding id="ellipsis">
    <content>
        <xul:label crop="end"><children/></xul:label>
    </content>
    <implementation>
        <field name="label">document.getAnonymousNodes(this)[0]</field>
        <field name="style">this.label.style</field>
        <property name="display">
            <getter>this.style.display</getter>
            <setter>if(this.style.display!= val)this.style.display=val</setter>
        </property>
        <property name="value">
            <getter>this.label.value</getter>
            <setter>if(this.label.value!=val)this.label.value=val</setter>
        </property>
        <method name="update">
            <body>
                var strings= this.textContent.split(/\s+/g)
                if(!strings[0])strings.shift()
                if(!strings[strings.length-1])strings.pop()
                this.value=strings.join('')
                this.display=strings.length?'':'none'
            </body>
        </method>
        <constructor>this.update()</constructor>
    </implementation>
    <handlers>
        <handler event="DOMSubtreeModified">this.update()</handler>
    </handlers>
</binding>
</bindings>

答案 2 :(得分:4)

如果您正在使用jQuery,我会使用great plugin

或者,[这个例子](404 NOT FOUND!)似乎可以跨浏览器工作。

有任何问题,请在评论中打我!

404链接:http://www.hedgerwow.com/360/dhtml/text_overflow/demo2.php

答案 3 :(得分:3)

新版本的CSS(CSS3)应该包含text-overflow:ellipsis,它会为您执行此操作。它目前适用于IE版本6及更高版本,以及Safari和Chrome。 Firefox不支持它,所以这还不是一个真正有用的答案,但值得记住的是,真正最好的方法最终是让CSS处理这个问题。

CSS3规范草案:http://www.w3.org/TR/2001/WD-css3-text-20010517/#text-overflow-props

支持的浏览器:http://www.quirksmode.org/css/contents.html(向下滚动到底部附近的“文字溢出”)

答案 4 :(得分:1)

很简单,不,没有更好的办法,不诉诸黑客。

例如,您可以使用一个位置:绝对跨度将“...”放在实际内容的顶部,并在容器上设置溢出:隐藏设置,并且只有在内容适合时才隐藏额外跨度容器。这让你只运行一次截断代码。

就个人而言,我只需要多次运行像素宽度计算。设置文本和读取宽度是一个快速的操作,因此它不应该是显而易见的。

答案 5 :(得分:1)

使用text-overflow:ellipsis。它不仅仅是IE ......大多数主流浏览器都可以做到这一点 但如果你不能here is a jQuery plugin这个。

答案 6 :(得分:1)

只回答你提出的一点:

  

所以,如果它是20个字符,我发现   它不适合,我必须   截断为19,添加省略号,和   然后检查它是否再次适合。然后   截断为18(加上省略号)和   再试一次。然后再次。和   再次...直到它适合。有没有   更好的方法?

找到正确长度的更快的方法是将字符串切成两半,测试它是否适合。如果是这样的话:重新加上原始长度的四分之一,如果它没有减掉四分之一,那么测试它是否适合。以原始长度的1/8,1 / 16,1 / 32,...递归重复,直到此加/减值小于1.

这是一种搜索算法:对于长度超过几个字的字符串,通常可以将需要在DOM中执行的测试数量减少10倍。

答案 7 :(得分:0)

试试这个:

Link One

更新

如果使用专有的{word-wrap:break-word;},IE将强制换行。现代浏览器可能具有默认的{overflow:visible;},并且它们会正常溢出,而不会扩展容器。

答案 8 :(得分:0)

不,这不是一项简单的任务。我不得不在一年前做同样的事情,发现甚至Internet Explorer(从版本6),Opera和Safari都可以做到,但没有Firefox。很抱歉,只有黑客才能救你

答案 9 :(得分:0)

答案 10 :(得分:0)

使用Opera:

-o-text-overflow:ellipsis;

答案 11 :(得分:0)

我从 Binyamin 的回复中将this.value=strings.join('')更改为this.value=strings.join(' '),这对我很有用!

答案 12 :(得分:0)

关于Firefox 4.0以及尚未实现的text-overflow:ellipsis CSS属性:

This链接为问题提供了部分解决方案。

仅使用css为text-overflow:ellipsis产生类似的结果。