Обрезать короткие строки PHP - PullRequest
2 голосов
/ 11 августа 2009

Как бы вы поступили, обрезая короткие строки, чтобы они не переходили к следующей строке в теге div. Например, моя строка message содержала следующее:

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

И я хочу предпочтительно отобразить его как

Мы предпочитаем вопросы, на которые можно ответить, а не просто обсудить. Обеспечить ... Подробнее

Я думаю оборвать строку, используя PHP, но тогда у вас возникнет следующая проблема

Вы можете видеть, что приведенная выше строка все еще может быть расширена. Любой способ сделать это или нет, спасибо заранее

Ответы [ 11 ]

4 голосов
/ 11 августа 2009

Используя PHP, вы можете использовать функцию wordwrap для выполнения усечения:

function truncate_to_length($text, $length, $text_if_longer = "...") 
{
    if (strlen($text) > $length) 
    {
        $text = wordwrap($text, $length);
        $text = substr($text, 0, strpos($text, "\n"));
        return $text . $text_if_longer;
    }
    return $text;
}
4 голосов
/ 11 августа 2009

Как вы можете сократить строку уже ответили, но ваш главный вопрос:

Как бы вы поступили, обрезая короткие строки , чтобы он не переходил к следующей строке в теге div

это не будет работать в большинстве случаев.

например:

iiiiiiiiii

wwwwwwwwww

Вы видите проблему?

это работает, только если ваши символы имеют одинаковую ширину, например:

iiiiiiiiii
wwwwwwwwww
1 голос
/ 09 мая 2012

Это функция, выбранная из шаблонов smarty, которая сокращает строки, не обрезая их.

function str_short($string, $length = 80, $etc = '...',
                              $break_words = false, $middle = false)
{
if ($length == 0)
    return '';

if (strlen($string) > $length) {
    $length -= min($length, strlen($etc));
    if (!$break_words && !$middle) {
        $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
    }
    if(!$middle) {
        return substr($string, 0, $length) . $etc;
    } else {
        return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
    }
} else {
    return $string;
}

}

1 голос
/ 12 августа 2009

следующие в основном работает; главная проблема заключается в том, что уведомление «... Читать дальше» может охватывать часть письма. Он также использует кучу презентационных элементов и требует JS. Это заставляет меня чувствовать себя нечистым.

Самый внешний элемент (класса .string) используется для установки общего размера. .text содержит текст для отображения. Между .string и .text в иерархии потомков находится элемент с большой шириной. Это помещает весь текст в .text в одну строку. JS используется для отображения или скрытия уведомления ... Подробнее ...

<style type="text/css">
  .string {
    height: 1em;
    width: 25%;
    position: relative; /* create containing block for children */
    border: 1px solid black;
    overflow: hidden;
    background: white; /* or whatever, as long as it's not "transparent". */
  }
  .string .line {
    width: 5000px; /* long enough for you? */
  }
  .string .notice {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 1;
    display: none;
    background: inherit; /* so that the notice will completely cover up whatever's beneath */
  }
</style>

<div class="string">
  <div class="line"><span class="text">We prefer questions that can be answered, 
    not just discussed. Provide details. Write clearly and simply. If your 
    question is about this website, ask it on meta instead.</span></div>
</div>
<hr />
<div class="string">
  <div class="line"><span class="text">Lorem ipsum dolor sit amet.</span></div>
</div>

<script>
  function isOverflowed(elt) {
      return elt.offsetWidth > elt.parentNode.parentNode.clientWidth;
  }
  function getNotice(textElt) {
       try {
           return (textElt.parentNode.parentNode.getElementsByClassName('notice'))[0];
       } catch (e) {
           return {style: {}};
       }
  }
  function show(elt) {
      elt.style.display = 'block';
  }
  function hide(elt) {
      elt.style.display = 'none';
  }
  function showReadMoreNotices() {
    var text=document.getElementsByClassName('text');
    for (var i=0; i<text.length; ++i) {
      if (isOverflowed(text[i])) {
          show(getNotice(text[i]));
      } else {
          hide(getNotice(text[i]));
      }
    }
  }

  var strings = document.getElementsByClassName('string');
  var notice = document.createElement('div');
  notice.appendChild(document.createTextNode('\u2026Read more'));
  notice.className = 'notice';
  for (var i=0; i<strings.length; ++i) {
      strings[i].appendChild(notice.cloneNode(true));
  }

  showReadMoreNotices();
  /* use your favorite event registration method here. Not that the traditional 
   * model is my favorite, it's just simple.
   */
  window.onresize = showReadMoreNotices;
</script>
1 голос
/ 11 августа 2009

Оооо, я придумал что-то, что работает, но не работает полностью ... Я хотел бы поделиться

div.string{

    height:15px;        
    overflow:hidden;
}

Это решает проблему, заключающуюся в том, что он будет скрывать все слово, которое не помещается в конец строки .., из-за переполнения, а высота установлена ​​только в одну строку. Однако вышеупомянутое все еще не делает проблему, показанную Руфином:

iiiiiiiiiiiiii

wwwwwwwwwwwwww

1 голос
/ 11 августа 2009

Вот пример, взятый из http://snippetdb.com/php/truncate-string:

function Truncate ($str, $length=10, $trailing='...')  
{ 
      // take off chars for the trailing 
      $length-=strlen($trailing); 
      if (strlen($str) > $length)  
      { 
         // string exceeded length, truncate and add trailing dots 
         return substr($str,0,$length).$trailing; 
      }  
      else  
      {  
         // string was already short enough, return the string 
         $res = $str;  
      } 

      return $res; 
} 
1 голос
/ 11 августа 2009

Проверьте размер, если размер больше вашего максимума, возьмите самые левые символы.

Самый левый # = общий размер - размер ("... читать дальше"). Затем добавьте перевод слева от большинства символов.

Jacob

0 голосов
/ 12 августа 2009

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

div.string {
    word-wrap: break-word;
}
0 голосов
/ 11 августа 2009

Если вы знаете, какой шрифт истинного типа использует браузер, вы можете использовать imagettfbbox () в библиотеке GD, чтобы вычислить ширину вашего текста. Затем итерируйте и удаляйте символы из конца текста, пока он не впишется в ваш div.

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

<?
    $width = 280;   // max. width in pixels that the text should have
    $font = 'C:\Windows\Fonts\verdana.TTF';
    $text = 'The quick brown fox jumps over the lazy dog';

    function getWidth($text) {
        list($x1, , $x2) = imagettfbbox(12, 0, $font, $text);
        return $x2-$x1;
    }

    while (getWidth($text.'...') > $width) $text = substr($text, 0, -1);
?>

<style type='text/css'>
    #my_div {
        font-family: Verdana; 
        font-size: 12pt; 
        border: 1px solid black; 
        width: 280px; 
        padding: 0
    }
</style>

<div id='my_div'>
    <?=$text?>...
</div>
0 голосов
/ 11 августа 2009

Было бы в принципе невозможно сделать это в PHP с не моноширинным шрифтом (даже с моноширинным шрифтом трудно точно сказать, как долго строка будет в определенном браузере. Единственный способ, которым я могу думать сделать это в браузере - это поместить его в a и установить ширину промежутка равной определенной ширине, а затем использовать overflow: hidden.

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