如何在 Firefox 中模仿 text-overflow: ellipsis?

发布于 2024-08-12 16:54:48 字数 2337 浏览 7 评论 0原文

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

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

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

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

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

编辑:我根据答案决定我原来的方法是最好的,除了我尝试通过不创建一个单独的 td 元素来简单地进行测量来改进上面链接中的解决方案,这感觉就像一个黑客。

这是我的代码:

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

And styles:

.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 被传递给函数。它适用于单个单词输入(例如“WWWWWWWWWWWWWWWWWW”),但不适用于多单词输入“WWWWWW WWWWW WWWWW”,因为它只是添加换行符并将文本测量为“WWWWW”的宽度。

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

I have some dynamic text contained in a div that is set to whatever a user enters in a textbox field. If the text doesn't fit in the div, right now it just gets cut off at the edge and all the text that extends past the border is not visible. I would like to truncate the text so that it fits inside the box and has an ellipsis (...) appended on the end. For example:

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

Obviously in the example it's easy because the code tag uses a fixed-width font so it's as simple as counting characters. I have a variable-width font so if they enter "WWWWWWWWWWW" it will fill up in much fewer characters than "................" would.

What's the best way to do this? I found a potential solution for simply finding the actual pixel width of the text here: http://www.codingforums.com/archive/index.php/t-100367.html

But even with a method like that, it's a bit awkward to implement the ellipsis. So if it's 20 characters and I find that it doesn't fit, I would have to truncate to 19, add the ellipsis, and then check if it fits again. Then truncate to 18 (plus the ellipsis) and try again. And again. And again...until it fit. Is there a better way?

EDIT: I have decided based on the answers that my original approach is best, except I have tried to improve on the solution in the link above by not creating a separate td element simply for measuring, which feels like a hack.

Here is my code:

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

And styles:

.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;
}

and the javascript that trims and adds the ellipsis:

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

The "line1" and "line2" divs get passed to the function. It works in the case of a single word input like "WWWWWWWWWWWWWWWWW" but does not work a multi-word input "WWWWW WWWWW WWWWW" because it just adds line breaks and measures the text as being the width of "WWWWW".

Is there a way I can fix this without resorting to copying the text into a hidden measuring element? Some way to set the style of the line divs so that they don't wrap text?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

沒落の蓅哖 2024-08-19 16:54:48

有什么方法可以设置行 div 的样式,使其不换行吗?

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

Some way to set the style of the line divs so that they don't wrap text?

There you have the white-space: nowrap for. Yes, this works in ancient browsers as well.

遗忘曾经 2024-08-19 16:54:48

这个问题在 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>

This issue must be working on Firefox too.

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>
眉目亦如画i 2024-08-19 16:54:48

如果您使用 jQuery,我会使用一个很棒的插件

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

有什么问题可以在评论里问我!

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

If you're using jQuery, there's a great plugin I use.

Alternatively, [this example] (404 NOT FOUND!) seems to work cross browser.

Any questions, hit me up in the comments!

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

东走西顾 2024-08-19 16:54:48

新版本的 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(向下滚动到底部附近的“text-overflow”)

The new version of CSS (CSS3) should include text-overflow:ellipsis, which does this for you. It currently works in IE versions 6 and up, as well as Safari and Chrome. It's not supported by Firefox, so this isn't really a useful answer yet, but it's worth keeping in mind that the real best way will, eventually, be to let CSS handle this.

CSS3 spec draft: http://www.w3.org/TR/2001/WD-css3-text-20010517/#text-overflow-props

Supported browsers: http://www.quirksmode.org/css/contents.html (scroll down to "text-overflow" near the bottom)

甜警司 2024-08-19 16:54:48

很简单,不,除了求助之外没有更好的方法。

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

就我个人而言,我只是多运行几次像素宽度计算。设置文本和读取宽度是一个快速操作,因此应该不会被注意到。

Quite simply, no, there's no better way without resorting to hacks.

You could, for example, use a position:absolute span to position your "..." on top of the actual content, with overflow:hidden set on the container, and only hide the extra span if the content fits within the container. That'd let you run the truncation code only once.

Personally, I'd just run the pixel width calculation a few extra times. Setting the text and reading the width is a fast operation, so it shouldn't be noticeable.

执手闯天涯 2024-08-19 16:54:48

使用text-overflow:ellipsis。它不仅仅适用于 IE...大多数主流浏览器都可以做到这一点。
但如果您不能这里是一个 jQuery 插件

Use text-overflow:ellipsis. Its not IE-only... Most major browser can do this.
But if you can't here is a jQuery plugin for this.

笨死的猪 2024-08-19 16:54:48

仅回答您提出的问题之一:

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

找到正确长度的一种更快的方法是将绳子切成两半,测试它是否合适。如果是这样:将原始长度的四分之一加回去,如果没有减少四分之一,则测试它是否合适。以原始长度的 1/8、1/16、1/32... 递归重复,直到该加/减值小于 1。

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

To answer just one of the points you raise:

So if it's 20 characters and I find
that it doesn't fit, I would have to
truncate to 19, add the ellipsis, and
then check if it fits again. Then
truncate to 18 (plus the ellipsis) and
try again. And again. And
again...until it fit. Is there a
better way?

A much faster way of finding the correct length is to cut the string in half, test that to see if it fits. If it does: add a quarter of the original length back on, and if it doesn't lop a quarter off, then test that to see if it fits. Repeat recursively with 1/8th, 1/16th, 1/32th, ... of the original length, until this add/subtract value is less than 1.

It's a seeking algorithm: for strings that are longer than just a few words you can typically cut the number of tests you need to perform in the DOM by a factor of 10.

橙味迷妹 2024-08-19 16:54:48

试试这个:

链接一

更新:

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

Try this:

Link One

Update:

If you use the proprietary {word-wrap: break-word;}, IE will force a line break. Modern browsers could have the default {overflow: visible;}, and they would overflow properly, without expanding the container.

陈年往事 2024-08-19 16:54:48

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

No, it's not simple task. I had to do same thing year ago and found that even Internet Explorer (from version 6), Opera and Safari can do it, but no Firefox. So sorry, only hacks can save you

椵侞 2024-08-19 16:54:48

与歌剧:

-o-text-overflow:ellipsis;

With Opera:

-o-text-overflow:ellipsis;
冰雪梦之恋 2024-08-19 16:54:48

我将 this.value=strings.join('')Binyamin 更改为 this.value=strings.join(' ')回复,这对我来说很好!

I changed this.value=strings.join('') to this.value=strings.join(' ') from Binyamin's reply, and it worked for me fine!

甲如呢乙后呢 2024-08-19 16:54:48

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

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

仅使用 CSS 即可产生与 text-overflow:ellipsis 类似的结果。

About Firefox 4.0 and the, still unimplemented, text-overflow:ellipsis CSS property:

This link gives a partial solution to the problem.

It produces a similar result to text-overflow:ellipsis using only css.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文