2010-06-28 44 views
8

Necesito un script de Jquery para truncar un texto párrafo por línea (no por número de caracteres).Jquery - Truncar texto por línea (no por número de caracteres)

Me gustaría lograr un bloque de texto uniformemente truncado. Debe tener un enlace "más" y "menos" para expandir y acortar el párrafo de texto. Mi párrafo del texto en un div con una clase, así:

<div class="content"> 
<h2>Headline</h2> 
<p>The paragraph Text here</p> 
</div> 

La solución más cercano que pude encontrar en SOF es la de abajo (pero `s para el elemento de área de texto y no funciona para mí): Limiting number of lines in textarea

Muchas gracias por cualquier consejo. Ben

Respuesta

0

Si utilizó una fuente monoespaciada, tendría una oportunidad en este trabajo, ya que tendría una buena idea de cuántas letras caben en cada línea, para un elemento de un ancho definido. Sin embargo, si una palabra se rompe en las líneas, entonces esto podría ser complicado ...

e: encontré otra pregunta que es básicamente lo que buscas: tampoco tenían una resolución, pero en mi opinión, la altura de la línea y la altura del elemento parecen ser las más cercanas.

"How can I count text lines inside a dom element"

1

por qué no hacer que el elemento p con overflow: hidden; da la altura de la línea fija, calcula la altura del div para que id contenga exactamente el número de líneas que requieras y el único cambio de la altura de la p de javascript.

p{ 
    overflow:hidden; 
    line-height:13px; 
    height:26px; /* show only 2 rows */ 
} 
<script type="text/javascript"> 
    function seeMoreRows(){ 
     $(p).height("52px"); 
    } 
</script> 
+0

Gracias por la sugerencia. Sin embargo, parece no ser lo suficientemente flexible ya que todos los párrafos en la página tienen una longitud diferente (en realidad es una lista de noticias). Si lo amplío a 52px, puede que no sea suficiente espacio para algunos y demasiado espacio para otros. Tiene que ser dinámico de alguna manera. –

+0

fue un ejemplo y creo que se puede calcular la nueva altura dinamicamente, pero la respuesta de Andy se ve mejor que mi idea. – jikhan

5

Para un enfoque básico, se puede echar un vistazo a la propiedad CSS line-height y el uso que en sus cálculos. Tenga en cuenta que este enfoque no tendrá en cuenta otros elementos en línea que son más grandes que esa altura (por ejemplo, imágenes).

Si quiere algo un poco más avanzado, puede obtener la información sobre cada línea usando la función getClientRects(). Esta función devuelve una colección de TextRectangle objetos con ancho, alto y desplazamiento para cada uno.

Vea this answer aquí para un ejemplo (aunque sea un objetivo no relacionado) de cómo funciona getClientRects().


actualización, tenía un poco de tiempo para volver y actualizar esta respuesta con un ejemplo real. Es básico, pero se entiende la idea:

http://jsbin.com/ukaqu3/2

Un par de consejos:

  • La colección devuelta por getClientRects es estática, no va a actualizar automáticamente si el elemento que contiene de las dimensiones cambian Mi ejemplo funciona alrededor de esto al capturar el evento de cambio de tamaño de la ventana.

  • Por algún extraño motivo de cumplimiento de normas que no entiendo, el elemento al que llama getClientRects activado debe ser un elemento en línea. En el ejemplo que tengo, utilizo un contenedor div con el texto en otro div dentro con display: inline.

+0

ese es el camino a seguir, seguro. No sabía de esto, +1 – dmp

+0

Parece algo que podría usarse, gracias. Sin embargo, lamentablemente no soy lo suficientemente inteligente como para juntar todo el script, incluido el enlace más/menos. ¿Alguien sabe cómo hacer esto? –

+0

@Bento: el verdadero problema es que javascript requiere que el contenido se represente primero y luego se modifique. De modo que tiene una solución de compromiso, ya sea procesar el contenido completo y reducirlo cuando esté listo, o dejarlo oculto y luego mostrar la cantidad que necesita cuando el documento está listo. Es un diseño muy torpe y es mejor que marques esta pregunta como respondida y hagas otra pregunta para obtener un mejor consejo. –

3

hice este pequeño código jQuery para permitirme trunco ​​bloques de texto por línea (a través de clases CSS), siento libre de usar y comentarlo.

Aquí está el jsFiddle, que también incluye funciones truncadas por cuenta de caracteres o cantidad de palabras. Usted puede ver que actualmente, cambiar el tamaño de la ventana no actualizará la visualización del bloque, estoy trabajando en ello.

/* 
* Truncate a text bloc after x lines 
* <p class="t_truncate_l_2">Lorem ipsum magna eiusmod sit labore.</p> 
*/ 
$("*").filter(function() { 
    return /t_truncate_l_/.test($(this).attr('class')); 
}).each(function() { 
    var el = $(this); 
    var content = el.text(); 
    var classList = el.attr('class').split(/\s+/); 
    $.each(classList, function(index, item){ 
     if(/^t_truncate_l_/.test(item)) { 
      var n = item.substr(13); 
      var lineHeight = parseInt(el.css('line-height')); 
      if(lineHeight == 1 || el.css('line-height') == 'normal') 
       lineHeight = parseInt(el.css('font-size')) * 1.3; 
      var maxHeight = n * lineHeight; 
      var truncated = $.trim(content); 
      var old; 
      if(el.height() > maxHeight) 
       truncated += '...'; 
      while(el.height() > maxHeight && old != truncated) { 
       old = truncated; 
       truncated = truncated.replace(/\s[^\s]*\.\.\.$/, '...'); 
       el.text(truncated); 
      } 
     } 
    }); 
}); 
-1

tl; dr - establece una altura en su div contenedor y luego usar el jQuery dotdotdot plugin

estaba a punto de tomar ejemplo impresionante de @Andy E en un plugin, pero luego se dio cuenta de https://github.com/BeSite/jQuery.dotdotdot podría sacar esto adelante . Nuestro caso de uso es que queremos mostrar una línea en anchos de escritorio y dos líneas en dispositivos móviles/tabletas.

Nuestro CSS simplemente establecerá el contenedor div en el equivalente de una o dos líneas de altura en consecuencia y luego el complemento dotdotdot parece manejar el resto.

0

Hice un pequeño módulo que funciona con contenido de texto puro, no se permiten etiquetas anidadas y sin relleno en el elemento que contiene texto (pero esta funcionalidad podría agregarse fácilmente).

El HTML:

<p class="ellipsis" data-ellipsis-max-line-count="3"> 
    Put some multiline text here 
</p> 

El Javascript/jQuery:

(function() { 

$(document).ready(function(){ 
    store_contents(); 
    lazy_update(1000); 
}); 

// Lazy update saves performance for other tasks... 
var lazy_update = function(delay) { 

    window.lazy_update_timeout = setTimeout(function(){ 

     update_ellipsis(); 

     $(window).one('resize', function() { 
      lazy_update(delay); 
     }); 

    }, delay); 
} 

var store_contents = function(){ 

    $('.ellipsis').each(function(){ 
     var p = $(this); 
     p.data('ellipsis-storage', p.html()); 
    }); 
} 

var update_ellipsis = function(){ 

    $('.ellipsis').each(function(){ 

     var p = $(this); 
     var max_line_count = p.data('ellipsis-max-line-count'); 
     var line_height = p.html('&nbsp').outerHeight(); 
     var max_height = max_line_count*line_height; 
     p.html(p.data('ellipsis-storage')); 
     var p_height = p.outerHeight(); 

     while(p_height > max_height){ 

      var content_arr = p.html().split(' '); 
      content_arr.pop(); 
      content_arr.pop(); 
      content_arr.push('...'); 
      p.html(content_arr.join(' ')); 
      p_height = p.outerHeight(); 
     } 
    }); 
} 

})(); 

espero que les guste!

Cuestiones relacionadas