Вставьте многоточие (…) в тег HTML, если содержимое слишком широкое

148

У меня есть веб-страница с эластичным макетом, который меняет свою ширину, если размер окна браузера изменяется.

В этом макете есть заголовки ( h2), которые будут иметь переменную длину (на самом деле это заголовки блогов, которые я не контролирую). В настоящее время - если они шире окна - они разбиты на две строки.

Существует ли элегантное, протестированное (кросс-браузерное) решение - например, с помощью jQuery - которое сокращает innerHTML этого тега заголовка и добавляет «...», если текст будет слишком широким, чтобы поместиться в одну строку на текущем экране / ширина контейнера?

Бламу
источник
1
Обновленный ответ 2014 года: stackoverflow.com/a/22811590/759452
Adrien Be
Я создал плагин на основе этого потока, который использует свойства CSS пробела и переноса слов для форматирования текста. github.com/nothrem/jQuerySmartEllipsis
Радек Печ

Ответы:

119

У меня есть решение, работающее в FF3, Safari и IE6 + с одним и многострочным текстом

.ellipsis {
    white-space: nowrap;
    overflow: hidden;
}

.ellipsis.multiline {
    white-space: normal;
}

<div class="ellipsis" style="width: 100px; border: 1px solid black;">Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
<div class="ellipsis multiline" style="width: 100px; height: 40px; border: 1px solid black; margin-bottom: 100px">Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>

<script type="text/javascript" src="/js/jquery.ellipsis.js"></script>
<script type="text/javascript">
$(".ellipsis").ellipsis();
</script>

jquery.ellipsis.js

(function($) {
    $.fn.ellipsis = function()
    {
        return this.each(function()
        {
            var el = $(this);

            if(el.css("overflow") == "hidden")
            {
                var text = el.html();
                var multiline = el.hasClass('multiline');
                var t = $(this.cloneNode(true))
                    .hide()
                    .css('position', 'absolute')
                    .css('overflow', 'visible')
                    .width(multiline ? el.width() : 'auto')
                    .height(multiline ? 'auto' : el.height())
                    ;

                el.after(t);

                function height() { return t.height() > el.height(); };
                function width() { return t.width() > el.width(); };

                var func = multiline ? height : width;

                while (text.length > 0 && func())
                {
                    text = text.substr(0, text.length - 1);
                    t.html(text + "...");
                }

                el.html(t.html());
                t.remove();
            }
        });
    };
})(jQuery);
Алекс
источник
22
Хорошо, я искал, как справиться с переполнением несколькими строками. Одно улучшение: вместо добавления трех периодов добавьте символ многоточия «…».
Симон Лишке
4
Это работает очень хорошо. Вы должны опубликовать это на сайте jQuery.
Эдгар
1
Хотя в IE, если функция многоточия применяется к элементу div, у которого есть только ссылка, после многоточия ссылка исчезает. Есть какие-нибудь указатели на это?
Chantz
6
Если вы хотите увидеть это в действии, вы можете увидеть его здесь (извините за неправильное форматирование кода плагина) jsfiddle.net/danesparza/TF6Rb/1
Дэн Эспарза,
22
Чтобы повысить производительность, выполните бинарный поиск вместо удаления одного символа за раз в цикле while. Если 100% текста не помещается, попробуйте 50% текста; затем 75% текста, если 50% подходит, или 25%, если 50% не подходит, и т. д.
StanleyH
182

Следующее CSS-решение для усечения текста в одну строку работает со всеми браузерами, перечисленными на http://www.caniuse.com на момент написания, за исключением Firefox 6.0. Обратите внимание, что JavaScript совершенно не нужен, если вам не требуется поддержка переноса многострочного текста или более ранних версий Firefox.

.ellipsis {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    -o-text-overflow: ellipsis;
}

Если вам нужна поддержка более ранних версий Firefox, проверьте мой ответ на этот другой вопрос .

Симон Лишке
источник
2
Это на несколько порядков быстрее, чем подход jQuery. Прекрасно работает в IE7 + и Chrome.
JDB до сих пор помнит Монику
3
Это хорошо работает и в древних браузерах. Мы успешно использовали его в Google в ~ 2004 году, где мы должны были поддерживать или грациозно ухудшать работу некоторых действительно браузерных браузеров.
ЭльБел
2
JS Fiddle для тех, кто хочет попробовать его в браузере - jsfiddle.net/r39Ad
Deepak Bala
@DilipRajkumar вам нужно будет предоставить более подробную информацию, например, пример JSFiddle, демонстрирующий, что он не работает в IE 8.
Саймон Лишке
1
@ SharpCoder вы не делаете. То, где текст обрезается, определяется шириной содержащего его элемента, то есть он усекается, когда он переполняет ширину элемента.
Симон Лишке,
40

Я построил этот код, используя ряд других постов, со следующими улучшениями:

  1. Он использует бинарный поиск, чтобы найти правильную длину текста.
  2. Он обрабатывает случаи, когда элементы (элементы) эллипса изначально скрыты, путем настройки события показа одного кадра, который повторно запускает код эллипса при первом отображении элемента. Это удобно для представлений основной детали или древовидных представлений, где некоторые элементы изначально не отображаются.
  3. При желании он добавляет атрибут заголовка с исходным текстом для эффекта наведения.
  4. Добавлено display: blockв стиль, поэтому пролет работает
  5. Он использует символ многоточия вместо 3 периодов.
  6. Он автоматически запускает скрипт для всего с классом .ellipsis

CSS:

.ellipsis {
        white-space: nowrap;
        overflow: hidden;
        display: block;
}

.ellipsis.multiline {
        white-space: normal;
}

jquery.ellipsis.js

(function ($) {

    // this is a binary search that operates via a function
    // func should return < 0 if it should search smaller values
    // func should return > 0 if it should search larger values
    // func should return = 0 if the exact value is found
    // Note: this function handles multiple matches and will return the last match
    // this returns -1 if no match is found
    function binarySearch(length, func) {
        var low = 0;
        var high = length - 1;
        var best = -1;
        var mid;

        while (low <= high) {
            mid = ~ ~((low + high) / 2); //~~ is a fast way to convert something to an int
            var result = func(mid);
            if (result < 0) {
                high = mid - 1;
            } else if (result > 0) {
                low = mid + 1;
            } else {
                best = mid;
                low = mid + 1;
            }
        }

        return best;
    }

    // setup handlers for events for show/hide
    $.each(["show", "toggleClass", "addClass", "removeClass"], function () {

        //get the old function, e.g. $.fn.show   or $.fn.hide
        var oldFn = $.fn[this];
        $.fn[this] = function () {

            // get the items that are currently hidden
            var hidden = this.find(":hidden").add(this.filter(":hidden"));

            // run the original function
            var result = oldFn.apply(this, arguments);

            // for all of the hidden elements that are now visible
            hidden.filter(":visible").each(function () {
                // trigger the show msg
                $(this).triggerHandler("show");
            });

            return result;
        };
    });

    // create the ellipsis function
    // when addTooltip = true, add a title attribute with the original text
    $.fn.ellipsis = function (addTooltip) {

        return this.each(function () {
            var el = $(this);

            if (el.is(":visible")) {

                if (el.css("overflow") === "hidden") {
                    var content = el.html();
                    var multiline = el.hasClass('multiline');
                    var tempElement = $(this.cloneNode(true))
                        .hide()
                        .css('position', 'absolute')
                        .css('overflow', 'visible')
                        .width(multiline ? el.width() : 'auto')
                        .height(multiline ? 'auto' : el.height())
                    ;

                    el.after(tempElement);

                    var tooTallFunc = function () {
                        return tempElement.height() > el.height();
                    };

                    var tooWideFunc = function () {
                        return tempElement.width() > el.width();
                    };

                    var tooLongFunc = multiline ? tooTallFunc : tooWideFunc;

                    // if the element is too long...
                    if (tooLongFunc()) {

                        var tooltipText = null;
                        // if a tooltip was requested...
                        if (addTooltip) {
                            // trim leading/trailing whitespace
                            // and consolidate internal whitespace to a single space
                            tooltipText = $.trim(el.text()).replace(/\s\s+/g, ' ');
                        }

                        var originalContent = content;

                        var createContentFunc = function (i) {
                            content = originalContent.substr(0, i);
                            tempElement.html(content + "…");
                        };

                        var searchFunc = function (i) {
                            createContentFunc(i);
                            if (tooLongFunc()) {
                                return -1;
                            }
                            return 0;
                        };

                        var len = binarySearch(content.length - 1, searchFunc);

                        createContentFunc(len);

                        el.html(tempElement.html());

                        // add the tooltip if appropriate
                        if (tooltipText !== null) {
                            el.attr('title', tooltipText);
                        }
                    }

                    tempElement.remove();
                }
            }
            else {
                // if this isn't visible, then hook up the show event
                el.one('show', function () {
                    $(this).ellipsis(addTooltip);
                });
            }
        });
    };

    // ellipsification for items with an ellipsis
    $(document).ready(function () {
        $('.ellipsis').ellipsis(true);
    });

} (jQuery));
Адам Теген
источник
2
Прекрасный. Браво за реализацию моего предложения бинарного поиска.
StanleyH
2
Просто быстрое примечание ... стоит добавить .css ('max-width', 'none') к tempElement var ... Таким образом, вы можете использовать объявление max-width в вашем css, делая плагин гораздо более гибким (по крайней мере, для большинства случаев использования у меня есть). Хорошая работа в любом случае. :)
gordyr
3
Это гораздо более быстрое внедрение, чем принятый выше ответ. Если у вас есть несколько элементов .ellipsis, и вы делаете с ними что-то динамическое, этот работает намного лучше.
Mjvotaw
Можете ли вы привести пример? Мой вопрос здесь: stackoverflow.com/questions/26344520/…
SearchForKnowledge
Бинарный поиск предпочтителен, но не с очень маленькими наборами данных, и в этом случае он снижает производительность по сравнению с прямым линейным поиском, таким как indexOf () ... очевидно
user1360809
20

Мой ответ поддерживает только однострочный текст. Ознакомьтесь с комментарием gfullam ниже для многострочного форка, он выглядит довольно многообещающе.

Я несколько раз переписывал код из первого ответа, и я думаю, что он должен быть самым быстрым.

Сначала он находит «предполагаемую» длину текста, а затем добавляет или удаляет символ, пока ширина не станет правильной.

Используемая логика показана ниже:

введите описание изображения здесь

После того, как «приблизительная» длина текста найдена, символы добавляются или удаляются, пока не будет достигнута желаемая ширина.

Я уверен, что это нуждается в некоторой настройке, но вот код:

(function ($) {
    $.fn.ellipsis = function () {
        return this.each(function () {
            var el = $(this);

            if (el.css("overflow") == "hidden") {
                var text = el.html().trim();
                var t = $(this.cloneNode(true))
                                        .hide()
                                        .css('position', 'absolute')
                                        .css('overflow', 'visible')
                                        .width('auto')
                                        .height(el.height())
                                        ;
                el.after(t);

                function width() { return t.width() > el.width(); };

                if (width()) {

                    var myElipse = "....";

                    t.html(text);

                    var suggestedCharLength = (text.length * el.width() / t.width()) - myElipse.length;

                    t.html(text.substr(0, suggestedCharLength) + myElipse);

                    var x = 1;
                    if (width()) {
                        while (width()) {
                            t.html(text.substr(0, suggestedCharLength - x) + myElipse);
                            x++;
                        }
                    }
                    else {
                        while (!width()) {
                            t.html(text.substr(0, suggestedCharLength + x) + myElipse);
                            x++;
                        }
                        x--;
                        t.html(text.substr(0, suggestedCharLength + x) + myElipse);
                    }

                    el.html(t.html());
                    t.remove();
                }
            }
        });
    };
})(jQuery);
Майки г
источник
3
Ваше решение может быть не лучшим, но оно очень хорошо объяснено. И мне нравится этот тип логики приближения. +1 :)
Флатер
2
Я разветвлял это, чтобы добавить поддержку текстовых областей и многострочного (вертикального) усечения многоточия: jsfiddle.net/gfullam/j29z7381 (мне нравится логика приближения BTW)
gfullam
19

На всякий случай, если вы окажетесь здесь в 2013 году - вот чистый подход CSS, который я нашел здесь: http://css-tricks.com/snippets/css/truncate-string-with-ellipsis/

.truncate {
  width: 250px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

Это работает хорошо.

Джозеф Юнке
источник
1
FWIW, text-overflowне работает с textareaэлементами (по состоянию на 2015). Если вам нужна поддержка, textareaвы можете добиться ее, изменив принятый ответ или воспользовавшись этим ответвлением .
Gfullam
18

Я сделал действительно крутой плагин jQuery для обработки всех разновидностей многоточия текста, который называется ThreeDots @ http://tpgblog.com/threedots

Он гораздо более гибкий, чем CSS-подходы, и поддерживает гораздо более сложные, настраиваемые способы поведения и взаимодействия.

Наслаждаться.

Джереми Хорн
источник
8

Более гибкий плагин jQuery, позволяющий вам сохранить элемент после многоточия (например, кнопку «read-more») и обновлять onWindowResize. Он также работает вокруг текста с разметкой:

http://dotdotdot.frebsite.nl

Matt
источник
Я только что протестировал этот плагин, но не смог заставить его работать. Trunk8 был лучшим выбором для меня.
Гильерме Гарнье
8

Плагин trunk8 jQuery поддерживает несколько строк и может использовать любой html, а не только символы многоточия, для суффикса усечения: https://github.com/rviscomi/trunk8

Демо здесь: http://jrvis.com/trunk8/

Элиот Сайкс
источник
да, но это древнее сейчас. похоже его не поддерживается?
user2513846
1
Похоже, что он активно поддерживается - на момент написания (март 2016 г.) проблемы и PR показывают недавнюю активность с участием создателя проекта.
Элиот Сайкс
5

На самом деле в CSS есть довольно простой способ сделать это, используя тот факт, что IE расширяет это нестандартными и поддерживает FF:after

Вы также можете сделать это в JS, если захотите, проверив scrollWidth цели и сравнив ее с шириной родительской, но imho это менее надежно.

Изменить: это, видимо, более развито, чем я думал. Поддержка CSS3 может вскоре появиться, и вам будут доступны некоторые несовершенные расширения.

Последнее хорошо читать.

annakata
источник
На самом деле я предпочитаю решение JS - потому что оно добавляет «...» только если текст шире, чем доступное пространство.
BlaM
3

Я недавно сделал что-то подобное для клиента. Вот версия того, что я для них сделал (пример протестирован во всех последних версиях браузера на Win Vista). Не идеально все вокруг доски, но может быть легко подправлено.

Демо: http://enobrev.info/ellipsis/

Код:

<html>
    <head>
        <script src="http://www.google.com/jsapi"></script>
        <script>            
            google.load("jquery", "1.2.6");
            google.setOnLoadCallback(function() {
                $('.longtext').each(function() {
                    if ($(this).attr('scrollWidth') > $(this).width()) {
                        $more = $('<b class="more">&hellip;</b>');

                        // add it to the dom first, so it will have dimensions
                        $(this).append($more);

                        // now set the position
                        $more.css({
                            top: '-' + $(this).height() + 'px',
                            left: ($(this).attr('offsetWidth') - $more.attr('offsetWidth')) + 'px'
                        });
                    }
                });
            });
        </script>

        <style>
            .longtext {
                height: 20px;
                width: 300px;
                overflow: hidden;
                white-space: nowrap;
                border: 1px solid #f00;
            }

            .more {
                z-index: 10;
                position: relative;
                display: block;
                background-color: #fff;
                width: 18px;
                padding: 0 2px;
            }
        </style>
    </head>
    <body>
        <p class="longtext">This is some really long text.  This is some really long text.  This is some really long text.  This is some really long text.</p>
    </body>
</html>
enobrev
источник
3

Ну, одно простое решение, которое не совсем добавляет «...», но предотвращает разбиение <h2> на две строки, заключается в добавлении этого бита css:

h2 {
    height:some_height_in_px; /* this is the height of the line */
    overflow:hidden; /* so that the second (or third, fourth, etc.)
                        line is not visible */
}

Я подумал об этом и придумал это решение: вам нужно обернуть текстовое содержимое вашего тега h2 другим тегом (например, span) (или, альтернативно, обернуть h2s чем-то, имеющим заданную высоту), а затем Вы можете использовать этот вид javascript, чтобы отфильтровать ненужные слова:

var elems = document.getElementById('conainter_of_h2s').
                     getElementsByTagName('h2');

    for ( var i = 0, l = elems.length; i < l; i++) {
        var span = elems.item(i).getElementsByTagName('span')[0];
        if ( span.offsetHeight > elems.item(i).offsetHeight ) {
            var text_arr = span.innerHTML.split(' ');
            for ( var j = text_arr.length - 1; j>0 ; j--) {
                delete text_arr[j];
                span.innerHTML = text_arr.join(' ') + '...';
                if ( span.offsetHeight <= 
                                        elems.item(i).offsetHeight ){
                    break;
                }
            }
        }
    }
Рамунс Усовс
источник
На самом деле я думал об использовании этого в качестве основы для возможного решения, но я понятия не имею, если - основываясь на этом - можно было бы выяснить, отображается ли весь текст сейчас или мне нужно его сократить и добавить " ... ". Просто отрезать это будет выглядеть странно.
BlaM
3

Вот еще одно решение JavaScript. Работает очень хорошо и очень быстро.

https://github.com/dobiatowski/jQuery.FastEllipsis

Протестировано на Chrome, FF, IE на Windows и Mac.

Адам Лукащик
источник
Хотя это не так автоматически, я нашел, что это более точное решение, чем ответ Адама Тегена . Этот сценарий требует, чтобы максимальное количество строк текста было указано вместо угадывания.
пончик
3

Есть решение для многострочного текста с чистым CSS. Он называется line-clamp, но работает только в браузерах webkit. Однако есть способ имитировать это во всех современных браузерах (все более новые, чем в IE8). Кроме того, он будет работать только на сплошном фоне, потому что вам нужно фоновое изображение, чтобы скрыть последние слова последней строки. Вот как это происходит:

Учитывая этот HTML:

<p class="example" id="example-1">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>

Вот CSS:

p {
    position:relative;
    line-height:1.4em;
    height:4.2em;      /* 3 times the line-height to show 3 lines */
}
p::after {
    content:"...";
    font-weight:bold;
    position:absolute;
    bottom:0;
    right:0;
    padding:0 20px 1px 45px;
    background:url(ellipsis_bg.png) repeat-y;
}

ellipsis_bg.png - изображение того же цвета, что и фон, оно будет иметь ширину около 100 пикселей и иметь ту же высоту, что и высота строки.

Это не очень красиво, так как ваш текст может быть вырезан в середине буквы, но в некоторых случаях это может быть полезно.

Ссылка: http://www.css-101.org/articles/line-clamp/line-clamp_for_non_webkit-based_browsers.php

Жюль Колле
источник
Это хорошо, но вы должны быть уверены, что ваш текст достаточно длинный, потому что этот CSS добавит «...», даже если текст достаточно короткий, чтобы поместиться в доступное пространство. Кстати: тот же ответ был предоставлен Апопии около месяца назад;)
BlaM
@BlaM Практически то же самое. Но я думаю, что уловка градиента аккуратна и этот код в CSS вместо SASS, поэтому я думаю, что стоит быть отдельным ответом.
Жюль Колле
3

Многострочный многоточечный чистый CSS для текстового контента:

.container{
    position: relative;  /* Essential */
    background-color: #bbb;  /* Essential */
    padding: 20px; /* Arbritrary */
}
.text {
    overflow: hidden;  /* Essential */
    /*text-overflow: ellipsis; Not needed */
    line-height: 16px;  /* Essential */
    max-height: 48px; /* Multiples of line-height */
}
.ellipsis {
    position: absolute;/* Relies on relative container */
    bottom: 20px; /* Matches container padding */
    right: 20px; /* Matches container padding */
    height: 16px; /* Matches line height */
    width: 30px; /* Arbritrary */
    background-color: inherit; /* Essential...or specify a color */
    padding-left: 8px; /* Arbritrary */
}
<div class="container">
    <div class="text">
        Lorem ipsum dolor sit amet, consectetur eu in adipiscing elit. Aliquam consectetur venenatis blandit. Praesent vehicula, libero non pretium vulputate, lacus arcu facilisis lectus, sed feugiat tellus nulla eu dolor. Nulla porta bibendum lectus quis euismod. Aliquam volutpat ultricies porttitor. Cras risus nisi, accumsan vel cursus ut, sollicitudin vitae dolor. Fusce scelerisque eleifend lectus in bibendum. Suspendisse lacinia egestas felis a volutpat. Aliquam volutpat ultricies porttitor. Cras risus nisi, accumsan vel cursus ut, sollicitudin vitae dolor. Fusce scelerisque eleifend lectus in bibendum. Suspendisse lacinia egestas felis a volutpat.
    </div>
    <div class="ellipsis">...</div>
</div>

Пожалуйста, проверьте фрагмент для живого примера.

Джейсон Уильямс
источник
2

Это похоже на Алекс, но делает это во время регистрации, а не линейно, и принимает параметр maxHeight.

jQuery.fn.ellipsis = function(text, maxHeight) {
  var element = $(this);
  var characters = text.length;
  var step = text.length / 2;
  var newText = text;
  while (step > 0) {
    element.html(newText);
    if (element.outerHeight() <= maxHeight) {
      if (text.length == newText.length) {
        step = 0;
      } else {
        characters += step;
        newText = text.substring(0, characters);
      }
    } else {
      characters -= step;
      newText = newText.substring(0, characters);
    }
    step = parseInt(step / 2);
  }
  if (text.length > newText.length) {
    element.html(newText + "...");
    while (element.outerHeight() > maxHeight && newText.length >= 1) {
      newText = newText.substring(0, newText.length - 1);
      element.html(newText + "...");
    }
  }
};
Дэйв Аарон Смит
источник
2

Существует простое решение jQuery от Devon Govett :

https://gist.github.com/digulla/5796047

Чтобы использовать, просто вызовите ellipsis () для объекта jQuery. Например:

$ ( "Оболочка") многоточие ().

Бламу
источник
Я как раз собирался опубликовать ту же ссылку. :)
Гамбо
Ссылка в этом посте мертва.
Джастин Таннер,
Я добавил
резервную
1

Я переписал функцию Алекса для использования в библиотеке MooTools. Я изменил его немного на переход слова, вместо того чтобы добавить многоточие в середине слова.

Element.implement({
ellipsis: function() {
    if(this.getStyle("overflow") == "hidden") {
        var text = this.get('html');
        var multiline = this.hasClass('multiline');
        var t = this.clone()
            .setStyle('display', 'none')
            .setStyle('position', 'absolute')
            .setStyle('overflow', 'visible')
            .setStyle('width', multiline ? this.getSize().x : 'auto')
            .setStyle('height', multiline ? 'auto' : this.getSize().y)
            .inject(this, 'after');

        function height() { return t.measure(t.getSize).y > this.getSize().y; };
        function width() { return t.measure(t.getSize().x > this.getSize().x; };

        var func = multiline ? height.bind(this) : width.bind(this);

        while (text.length > 0 && func()) {
            text = text.substr(0, text.lastIndexOf(' '));
            t.set('html', text + "...");
        }

        this.set('html', t.get('html'));
        t.dispose();
    }
}
});
я люблю Италию
источник
1

Я не смог найти скрипт, который работал бы точно так, как я хотел, и мой jQuery - довольно много вариантов, которые можно было бы установить с большим количеством :)

https://github.com/rmorse/AutoEllipsis

rmorse
источник
1

Я был немного удивлен поведением CSS, хотя.

var cssEllipsis = 
{   "width": "100%","display": "inline-block", 
"vertical-align": "middle", "white-space": "nowrap", 
"overflow": "hidden", "text-overflow": "ellipsis" 
};

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

Premanshu
источник
1

ДЕЛАЙТЕ ЭЛЛИПСИС, ИСПОЛЬЗУЯ ТОЛЬКО CSS

<html>
<head>
<style type="text/css">
#ellipsisdiv {
    width:200px;
    white-space: nowrap;  
    overflow: hidden;  
    text-overflow: ellipsis;  
}  
</style>
</head>
<body>
<div id="ellipsisdiv">
This content is more than 200px and see how the the ellipsis comes at the end when the content width exceeds the div width.
</div>
</body>
</html>

* Этот код работает в большинстве современных браузеров. Если у вас возникли проблемы с Opera и IE (что, вероятно, не сработает), добавьте их в стиле:

-o-text-overflow: ellipsis;  
-ms-text-overflow: ellipsis;

* Эта функция является частью CSS3. Его полный синтаксис:

text-overflow: clip|ellipsis|string;
Робин Ризви
источник
1

Вот хорошая библиотека виджетов / плагинов со встроенным многоточием: http://www.codeitbetter.co.uk/widgets/ellipsis/ Все, что вам нужно сделать, это сделать ссылку на библиотеку и вызвать следующее:

<script type="text/javascript"> 
   $(document).ready(function () { 
      $(".ellipsis_10").Ellipsis({ 
         numberOfCharacters: 10, 
         showLessText: "less", 
         showMoreText: "more" 
      }); 
   }); 
</script> 
<div class="ellipsis_10"> 
   Some text here that's longer than 10 characters. 
</div>
Тим
источник
1

Вы можете сделать это намного проще только с помощью css, например: sass mode

.truncatedText {
   font-size: 0.875em;
   line-height: 1.2em;
   height: 2.4em; // 2 lines * line-height
   &:after {
      content: " ...";
   }
}

и у вас есть многоточие;)

Апопий Думитру
источник
0

Точно так же, как @acSlater, я не мог найти что-то для того, что мне было нужно, поэтому я сделал свой собственный. Совместное использование в случае, если кто-то еще может использовать:

Метод:
ellipsisIfNecessary(mystring,maxlength);
Использование:
trimmedString = ellipsisIfNecessary(mystring,50);
Код и демонстрационная ссылка: https://gist.github.com/cemerson/10368014
Кристофер Д. Эмерсон
источник
Две аннотации: а) Этот код не проверяет фактический размер элемента HTML. Вам необходимо указать заданную длину - это может быть необходимой функциональностью, но на самом деле это тривиально. б) Вы просто добавляете «...» в конец строки. Есть многоточие «…», которое вы можете / должны использовать.
BlaM
Привет @BlaM - код на самом деле проверяет длину по параметру maxlength. Это работает для меня по крайней мере. Тем не менее, это просто мой скромный раз для моей конкретной ситуации. Не стесняйтесь использовать любое из вышеуказанных решений, если оно не подходит для вашей ситуации.
Кристофер Д. Эмерсон
Да, он работает с «длиной», но не с «шириной» (размером в пикселях).
BlaM
Интересная идея - не стесняйтесь делать обновленную версию с поддержкой для этого. Мне это не нужно сейчас, но может пригодиться в будущем.
Кристофер Д. Эмерсон
0
<html>
<head>
    <!-- By Warren E. Downs, copyright 2016.  Based loosely on a single/multiline JQuery using example by Alex,
    but optimized to avoid JQuery, to use binary search, to use CSS text-overflow: ellipsis for end,
    and adding marquee option as well.
    Credit: Marquee: http://jsfiddle.net/jonathansampson/xxuxd/
            JQuery version: http://stackoverflow.com/questions/536814/insert-ellipsis-into-html-tag-if-content-too-wide
            (by Alex, http://stackoverflow.com/users/71953/alex)
            (Improved with Binary Search as suggested by StanleyH, http://stackoverflow.com/users/475848/stanleyh)
    -->
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
    <style>

        .single {
            overflow:hidden;
            white-space: nowrap;
            width: 10em;
            padding: 10px;
            margin: 0 auto;
            border: solid 1px blue;
        }

        .multiline {
            overflow: hidden;
            white-space: wrap;
            width: 10em;
            height: 4.5em;
            padding: 10px;
            margin: 0 auto;
            border: solid 1px blue;
        }

        .marquee {
            overflow: hidden;
            width: 40em;
            padding: 10px;
            margin: 0 auto;
            border: solid 1px blue;
        }

</style>
    <script>
        var _marqueeNumber=0;
        // mode=start,end,middle
        function clipText(text, len, mode) {
            if(!mode) { mode="end"; }
            else { mode=mode.toLowerCase(); }
            if(mode == "start") { return "&hellip;"+clipText(text,len,"_start"); }
            if(mode == "_start") { return text.substr(text.length - len); }
            if(mode == "middle") { 
                return clipText(text, len/2, "end") + clipText(text, len/2, "_start");
            }
            return text.substr(0, len) + "&hellip;";
        }

        function generateKeyframes(clsName, start, end) {
            var sec=5;
            var totalLen=parseFloat(start)-parseFloat(end);
            if(start.indexOf('em') > -1)      { sec=Math.round(totalLen/3); }
            else if(start.indexOf('px') > -1) { sec=Math.round(totalLen/42); }

            var style = document.createElement('style');
            style.type = 'text/css';
            style.innerHTML = 'body {}';
            document.getElementsByTagName('head')[0].appendChild(style);
            this.stylesheet = document.styleSheets[document.styleSheets.length-1];
            try {
                this.stylesheet.insertRule('.'+clsName+' {\n'+
                    '    animation: '+clsName+' '+sec+'s linear infinite;\n'+
                    '}\n', this.stylesheet.rules.length);
                this.stylesheet.insertRule('.'+clsName+':hover {\n'+
                    '    animation-play-state: paused\n'+
                    '}\n', this.stylesheet.rules.length);
                this.stylesheet.insertRule('@keyframes '+clsName+' {\n'+
                    '    0%   { text-indent: '+start+' }\n'+
                    '    100% { text-indent: '+end+' }\n'+
                    '}', this.stylesheet.rules.length);
            } catch (e) {
                console.log(e.message);
            }
        }

        function addClone(el, multiline, estyle) {
            if(!estyle) { 
                try { estyle=window.getComputedStyle(el); }
                catch(e) { return null; }
            }
            var t = el.cloneNode(true);
            var s=t.style;
            //s.display='none';
            s.visibility='hidden'; // WARNING: Infinite loop if this is not hidden (e.g. while testing)
            s.display='inline-block';
            s.background='black';
            s.color='white';
            s.position='absolute';
            s.left=0;
            s.top=0;
            s.overflow='visible';
            s.width=(multiline ? parseFloat(estyle.width) : 'auto');
            s.height=(multiline ? 'auto' : parseFloat(estyle.height));

            el.parentNode.insertBefore(t, el.nextSibling);

            return t;
        }
        function getTextWidth(el, multiline) {
            var t=addClone(el, multiline);
            if(!t) { return null; }
            var ts=window.getComputedStyle(t);
            var w=ts.width;
            if(multiline) {
                var es=window.getComputedStyle(el);
                var lines=Math.round(parseInt(ts.height)/parseInt(es.height))*2+0.5;
                w=w+'';
                var unit=''; // Extract unit
                for(var xa=0; xa<w.length; xa++) {
                    var c=w[xa];
                    if(c <= '0' || c >= '9') { unit=w.substr(xa-1); }
                }
                w=parseFloat(w);
                w*=lines; // Multiply by lines
                w+=unit; // Append unit again
            }
            t.parentNode.removeChild(t);
            return w;
        }

        // cls=class of element to ellipsize
        // mode=start,end,middle,marq (scrolling marquee instead of clip)
        function ellipsis(cls, mode) {
            mode=mode.toLowerCase();
            var elems=document.getElementsByClassName(cls);
            for(xa in elems) {
                var el=elems[xa];
                var multiline = el.className ? el.className.indexOf('multiline') > -1 : true;
                if(mode == "marq") {       
                    var w=getTextWidth(el, multiline);
                    if(!w) { continue; }
                    var mCls="dsmarquee"+(_marqueeNumber++);
                    var es=window.getComputedStyle(el);
                    generateKeyframes(mCls,es.width, '-'+w);
                    el.className+=" "+mCls; 
                    continue; 
                }
                if(mode == "end" && !multiline) { el.style.textOverflow="ellipsis"; continue; }
                var estyle=null;
                try { estyle=window.getComputedStyle(el); }
                catch(e) { continue; }
                if(estyle.overflow == "hidden") {
                    var text = el.innerHTML;
                    var t=addClone(el, multiline, estyle);

                    function height() {
                        var ts=window.getComputedStyle(t);
                        var es=window.getComputedStyle(el);
                        return parseFloat(ts.height) - parseFloat(es.height); 
                    }
                    function width() { 
                        var ts=window.getComputedStyle(t);
                        var es=window.getComputedStyle(el);
                        return parseFloat(ts.width) - parseFloat(es.width); 
                    }

                    var tooLong = multiline ? height : width;

                    var len=text.length;
                    var diff=1;
                    var olen=0;
                    var jump=len/2;
                    while (len > 0) {
                        var diff=tooLong();
                        if(diff > 0) { len-=jump; jump/=2; }
                        else if(diff < 0) { len+=jump; }
                        len=Math.round(len);
                        //alert('len='+len+';olen='+olen+';diff='+diff+';jump='+jump+';t='+JSON.stringify(t.innerHTML));
                        t.innerHTML=clipText(text, len, mode);
                        if(olen == len) { break; }
                        olen=len;
                    }
                    el.innerHTML=t.innerHTML;
                    t.parentNode.removeChild(t);
                }           
                //break;
                t.style.visibility='hidden';
            }
        }

        function testHarness() {
            ellipsis('ellipsis1', 'start'); 
            ellipsis('ellipsis2', 'end'); 
            ellipsis('ellipsis3', 'middle'); 
            ellipsis('marquee', 'marq')
        }
    </script>
    </head>
    <body onload="testHarness()">
    <div class="single ellipsis1" style="float:left">some long text that should be clipped left</div>
    <div class="single ellipsis2" style="float:right">right clip long text that should be clipped</div>
    <div class="single ellipsis3" style="float:center">some long text that should be clipped in the middle</div>

    <br />

    <p class="single marquee">Windows 8 and Windows RT are focused on your lifeyour friends and family, your apps, and your stuff. With new things like the <a href="http://windows.microsoft.com/en-US/windows-8/start-screen">Start screen</a>, <a href="http://windows.microsoft.com/en-US/windows-8/charms">charms</a>, and a <a href="http://windows.microsoft.com/en-US/windows-8/microsoft-account">Microsoft account</a>, you can spend less time searching and more time doing.</p>
    &nbsp;

    <br />

    <div class="multiline ellipsis1" style="float:left">Test test test test test test, some more long text, such as asdasdasdasdasd, that should be multiline clipped left(*)</div>

    <div class="multiline ellipsis2" style="float:right">right clip multiline long text, such as Test test test test test test, and some more long text that should be multiline clipped right.</div>

    <div class="multiline ellipsis3" style="float:center">Test test test test test test, some more long text, such as asdasdasdasdasd, that should be multiline clipped in the middle(*)</div>

    <br />

    <p class="multiline marquee">Multiline Marquee: Windows 8 and Windows RT are focused on your lifeyour friends and family, your apps, and your stuff. With new things like the <a href="http://windows.microsoft.com/en-US/windows-8/start-screen">Start screen</a>, <a href="http://windows.microsoft.com/en-US/windows-8/charms">charms</a>, and a <a href="http://windows.microsoft.com/en-US/windows-8/microsoft-account">Microsoft account</a>, you can spend less time searching and more time doing.</p>
    &nbsp;

    </body>
</html>
Уоррен Даунс
источник