Подтвердить что ты не робот

Как я могу имитировать переполнение текста: эллипсис в Firefox?

У меня есть динамический текст, содержащийся в 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 (плюс многоточие) и повторите попытку. И опять. И снова... пока это не подойдет. Есть ли лучший способ?

EDIT: Я решил основать на ответах, что мой оригинальный подход лучше всего, за исключением того, что я попытался улучшить решение в ссылке выше, не создавая отдельный элемент 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>

И стили:

.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" передаются функции. Он работает в случае ввода одного слова как "WWWWWWWWWWWWWWWWWW", но не работает многословный ввод "WWWWW WWWWW WWWWW", потому что он просто добавляет разрывы строк и измеряет текст как ширину "WWWWW".

Есть ли способ исправить это, не прибегая к копированию текста в скрытый измерительный элемент? Какой-то способ установить стиль разделителей строк так, чтобы они не обертывали текст?

4b9b3361

Ответ 1

Какой-то способ задать стиль разделителей строк, чтобы они не обтекали текст?

Там у вас есть white-space: nowrap для. Да, это работает и в древних браузерах.

Ответ 2

Эта проблема также должна работать на 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>

Ответ 3

Если вы используете jQuery, там отличный плагин, который я использую.

В качестве альтернативы [этот пример] (404 NOT FOUND!), похоже, работает с перекрестным браузером.

Любые вопросы, попавшие мне в комментарии!

404 ссылка: http://www.hedgerwow.com/360/dhtml/text_overflow/demo2.php

Ответ 4

Новая версия CSS (CSS3) должна включать text-overflow:ellipsis, что делает это для вас. В настоящее время он работает в версиях IE версии 6 и выше, а также в Safari и Chrome. Это не поддерживается Firefox, так что пока это не очень полезный ответ, но стоит иметь в виду, что лучшим вариантом будет, в конечном итоге, позволить CSS справиться с этим.

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

Поддерживаемые браузеры: http://www.quirksmode.org/css/contents.html (прокрутите вниз до "text-overflow" внизу)

Ответ 5

Совершенно просто, нет, нет лучшего способа, не прибегая к хакам.

Вы могли бы, например, использовать позицию: абсолютный диапазон для размещения вашего "..." поверх фактического содержимого, с переполнением: скрытым, установленным в контейнере, и только скрыть дополнительный диапазон, если содержимое вписывается в контейнер. Это позволит вам запускать код усечения только один раз.

Лично я просто запустил вычисление ширины пикселя несколько раз. Настройка текста и чтение ширины - это быстрая операция, поэтому она не должна быть заметной.

Ответ 7

Чтобы ответить только на один из поднятых вами пунктов:

Итак, если это 20 символов, и я нахожу что он не подходит, мне придется усечь до 19, добавить многоточие и затем проверьте, подходит ли он снова. затем усечь до 18 (плюс многоточие) и попробуй еще раз. И опять. А также снова... пока он не подойдет. Есть ли лучший способ?

Более быстрый способ нахождения правильной длины состоит в том, чтобы вырезать строку пополам, проверить это, чтобы увидеть, подходит ли она. Если это так: добавьте четверть первоначальной длины назад, и если она не выйдет на четверть, проверьте ее, чтобы она соответствовала. Повторите рекурсивно с 1/8th, 1/16th, 1/32th,... исходной длины, пока это значение add/subtract не станет меньше.

Это алгоритм поиска: для строк, которые длиннее нескольких слов, вы обычно можете сократить количество тестов, которые необходимо выполнить в DOM, в 10 раз.

Ответ 8

Попробуйте следующее:

Ссылка 1

Update:

Если вы используете проприетарный {word-wrap: break-word;}, IE заставит разрыв строки. Современные браузеры могут иметь значение по умолчанию {overflow: visible;}, и они будут переполняться должным образом, не расширяя контейнер.

Ответ 9

Нет, это не простая задача. Я должен был сделать то же самое год назад и обнаружил, что даже Internet Explorer (с версии 6), Opera и Safari могут это сделать, но не Firefox. Извините, только хаки могут спасти вас.

Ответ 11

С Opera:

-o-text-overflow:ellipsis;

Ответ 12

Я изменил this.value=strings.join('') на this.value=strings.join(' ') из ответа Binyamin, и это сработало для меня хорошо!

Ответ 13

О Firefox 4.0 и свойства, еще не реализованные, text-overflow:ellipsis CSS:

Эта ссылка дает частичное решение проблемы.

Он производит аналогичный результат для text-overflow:ellipsis, используя только css.