Кросс-браузерный многострочный переполнение текста с добавлением многоточия в пределах фиксированной ширины и высоты `<div>` - PullRequest
165 голосов
/ 04 августа 2010

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

Можно ли создать многоточие на <div> с фиксированной шириной и несколькими строками?

text-overflow

Я попробовал несколько плагинов jQuery тут и там, но не могу найти тот, который ищу.Любая рекомендация?Идеи?

Ответы [ 23 ]

86 голосов
/ 07 октября 2010

Просто быстрая основная идея.

Я тестировал со следующей разметкой:

<div id="fos">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin nisi ligula, dapibus a volutpat sit amet, mattis et dui. Nunc porttitor accumsan orci id luctus. Phasellus ipsum metus, tincidunt non rhoncus id, dictum a lectus. Nam sed ipsum a lacus sodales eleifend. Vestibulum lorem felis, rhoncus elementum vestibulum eget, dictum ut velit. Nullam venenatis, elit in suscipit imperdiet, orci purus posuere mauris, quis adipiscing ipsum urna ac quam.</p>  
</div>

И CSS:

#fos { width: 300px; height: 190px; overflow: hidden; }
#fos p { padding: 10px; margin: 0; }

Применение этого jQuery приведет к желаемому результату:

var $p = $('#fos p');
var divh = $('#fos').height();
while ($p.outerHeight() > divh) {
    $p.text(function (index, text) {
        return text.replace(/\W*\s(\S)*$/, '...');
    });
}

Он многократно пытается удалить последнее слово текста, пока не достигнет желаемого размера. Из-за переполнения: скрыто; процесс остается невидимым, и даже при отключенном JS результат остается «визуально правильным» (конечно, без «...»).

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

Опять же, это не полное решение, просто идея.

ОБНОВЛЕНИЕ: Добавлено jsFiddle Demo .

67 голосов
/ 13 сентября 2011

Попробуйте подключаемый модуль jQuery.dotdotdot .

$(".ellipsis").dotdotdot();
21 голосов
/ 03 марта 2016

библиотеки Javascript для "зажима строки"

Обратите внимание, что «зажим линии» также обозначается как «Многоточие на блоке из нескольких линий» или «Вертикальный многоточие».


github.com / бесите / jQuery.dotdotdot


github.com / josephschmitt / Clamp.js


Вот еще несколько, которые я еще не исследовал:


CSS решения для зажима линий

Существует несколько CSS-решений, но самое простое использует -webkit-line-clamp, у которого плохая поддержка браузера . Смотрите живую демонстрацию на jsfiddle.net / AdrienBe / jthu55v7 /

Многие люди приложили немало усилий, чтобы сделать это, используя только CSS. Смотрите статьи и вопросы по этому поводу:


Что бы я порекомендовал

Будьте проще. Если у вас нет достаточно времени, чтобы посвятить эту функцию, выберите самое простое и проверенное решение: простой CSS или хорошо протестированную библиотеку javascript.

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


Что делают другие

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

AirBnb

О, и если вы ищете вдохновение для дизайна:

6 голосов
/ 17 мая 2012

В HTML нет такой функции, и это очень расстраивает.

Я разработал библиотеку , чтобы справиться с этим.

  • Многострочное переполнение текста: многоточие
  • Многострочный текст с технологиями, которые его не поддерживают: SVG, Canvas, например
  • Точно такие же разрывы строк в тексте SVG, в рендеринге HTML и в экспорте PDF, например

Проверьте мой сайт для скриншота, учебника и ссылки для скачивания.

4 голосов
/ 23 мая 2013

У меня есть решение, которое работает хорошо, но вместо многоточия оно использует градиент. Преимущества в том, что вам не нужно выполнять какие-либо вычисления JavaScript, и это работает для контейнеров переменной ширины, включая ячейки таблицы. Он использует пару дополнительных элементов div, но его очень легко реализовать.

http://salzerdesign.com/blog/?p=453

Редактировать: Извините, я не знал, что ссылки недостаточно. Решение состоит в том, чтобы поместить div вокруг текста и стилизовать div, чтобы контролировать переполнение. Внутри div поместите еще один div с градиентом затухания, который можно сделать с помощью CSS или изображения (для старого IE). Градиент переходит от прозрачного к цвету фона ячейки таблицы и немного шире многоточия. Если текст длинный и переполняется, он попадает под div «fade» и выглядит «блеклым». Если текст короткий, исчезновение не видно, поэтому проблем нет. Два контейнера можно настроить так, чтобы одна или несколько строк отображались путем установки высоты контейнера, кратной высоте текстовой строки. Div "Fade" может быть расположен только для последней строки.

4 голосов
/ 30 марта 2013

Чистое решение JS, основанное на решении bažmegakapa, и некоторая очистка для учета людей, которые пытаются дать высоту / максимальную высоту, которая меньше, чем у элемента lineHeight:

  var truncationEl = document.getElementById('truncation-test');
  function calculateTruncation(el) {
    var text;
    while(el.clientHeight < el.scrollHeight) {
      text = el.innerHTML.trim();
      if(text.split(' ').length <= 1) {
        break;
      }
      el.innerHTML = text.replace(/\W*\s(\S)*$/, '...');
    }
  }

  calculateTruncation(truncationEl);
3 голосов
/ 27 мая 2014

Вот простой способ CSS сделать это: http://www.mobify.com/blog/multiline-ellipsis-in-pure-css/

Вот резюме:

enter image description here

<html>
<head>
<style>
    html, body, p { margin: 0; padding: 0; font-family: sans-serif;}

    .ellipsis {
        overflow: hidden;
        height: 200px;
        line-height: 25px;
        margin: 20px;
        border: 5px solid #AAA; }

    .ellipsis:before {
        content:"";
        float: left;
        width: 5px; height: 200px; }

    .ellipsis > *:first-child {
        float: right;
        width: 100%;
        margin-left: -5px; }        

    .ellipsis:after {
        content: "\02026";  

        box-sizing: content-box;
        -webkit-box-sizing: content-box;
        -moz-box-sizing: content-box;

        float: right; position: relative;
        top: -25px; left: 100%; 
        width: 3em; margin-left: -3em;
        padding-right: 5px;

        text-align: right;

        background: -webkit-gradient(linear, left top, right top,
            from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));
        background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);           
        background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
        background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
        background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); }
</style>
</head>
<body>
    <div class="ellipsis">
        <div>
            <p>Call me Ishmael.....</p> 
        </div>
    </div>
</body>
</html>
2 голосов
/ 01 декабря 2015

Вот ванильное решение JavaScript, которое можно использовать в крайнем случае:

// @param 1 = element containing text to truncate
// @param 2 = the maximum number of lines to show
function limitLines(el, nLines) {
  var nHeight,
    el2 = el.cloneNode(true);
  // Create clone to determine line height
  el2.style.position = 'absolute';
  el2.style.top = '0';
  el2.style.width = '10%';
  el2.style.overflow = 'hidden';
  el2.style.visibility = 'hidden';
  el2.style.whiteSpace = 'nowrap';
  el.parentNode.appendChild(el2);
  nHeight = (el2.clientHeight+2)*nLines; // Add 2 pixels of slack
  // Clean up
  el.parentNode.removeChild(el2);
  el2 = null;
  // Truncate until desired nLines reached
  if (el.clientHeight > nHeight) {
    var i = 0,
      imax = nLines * 35;
    while (el.clientHeight > nHeight) {
      el.innerHTML = el.textContent.slice(0, -2) + '&hellip;';
      ++i;
      // Prevent infinite loop in "print" media query caused by
      // Bootstrap 3 CSS: a[href]:after { content:" (" attr(href) ")"; }
      if (i===imax) break;
    }
  }
}

limitLines(document.getElementById('target'), 7);
#test {
  width: 320px;
  font-size: 18px;
}
<div id="test">
  <p>Paragraph 1</p>
  <p id="target">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>
  <p>Paragraph 3</p>
</div>

Вы можете поиграть с ним в коде ниже. Попробуйте изменить размер шрифта на панели CSS и внесите незначительные изменения в панель HTML (например, добавить дополнительный пробел где-нибудь), чтобы обновить результаты. Независимо от размера шрифта средний абзац всегда должен быть обрезан до количества строк во втором параметре, переданном limitLines ().

Codepen: http://codepen.io/thdoan/pen/BoXbEK

1 голос
/ 03 октября 2018

Очень простое решение javascript. Divs должен быть в стиле f.e.:

.croppedTexts { 
  max-height: 32px;
  overflow: hidden;
}

И JS:

var list = document.body.getElementsByClassName("croppedTexts");
for (var i = 0; i < list.length; i++) {
  cropTextToFit(list[i]);
}

function cropTextToFit (o) {
  var lastIndex;
  var txt = o.innerHTML;
  if (!o.title) o.title = txt;

  while (o.scrollHeight > o.clientHeight) {
    lastIndex = txt.lastIndexOf(" ");
    if (lastIndex == -1) return;
    txt = txt.substring(0, lastIndex);
    o.innerHTML = txt + "…";
  }
}
1 голос
/ 05 сентября 2014

Не точный ответ на вопрос, но я наткнулся на эту страницу, когда пытался сделать очень похожее, но хотел добавить ссылку для «просмотра большего», а не просто многоточия. Это функция jQuery, которая добавляет ссылку «еще» к тексту, который переполняет контейнер. Лично я использую это с Bootstrap, но, конечно, он будет работать без.

Example more screenshot

Чтобы использовать, поместите свой текст в контейнер следующим образом:

<div class="more-less">
    <div class="more-block">
        <p>The long text goes in here</p>
    </div>
</div>

Когда добавлена ​​следующая функция jQuery, любой из div, который больше значения регулировки высоты, будет усечен и будет добавлена ​​ссылка «Еще».

$(function(){
    var adjustheight = 60;
    var moreText = '+ More';
    var lessText = '- Less';
    $(".more-less .more-block").each(function(){
        if ($(this).height() > adjustheight){
            $(this).css('height', adjustheight).css('overflow', 'hidden');
            $(this).parent(".more-less").append
                ('<a style="cursor:pointer" class="adjust">' + moreText + '</a>');
        }
    });
    $(".adjust").click(function() {
        if ($(this).prev().css('overflow') == 'hidden')
        {
            $(this).prev().css('height', 'auto').css('overflow', 'visible');
            $(this).text(lessText);
        }
        else {
            $(this).prev().css('height', adjustheight).css('overflow', 'hidden');
            $(this).text(moreText);
        }
    });
});

На основании этого, но обновлено: http://shakenandstirredweb.com/240/jquery-moreless-text

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...