working varias truncar texto suspensivos puntos not lineas desbordado con javascript html css css3

javascript - varias - Puntos suspensivos de desbordamiento de texto en el lado izquierdo



truncar texto con puntos suspensivos (9)

¿Por qué no solo usar la direction:rtl;

Tengo una lista de rutas (a falta de una palabra mejor, quizás las rutas de migas de pan las describen mejor). Algunos de los valores son demasiado largos para mostrarlos en su padre, así que estoy usando text-overflow: ellipsis . El problema es que la información importante está a la derecha, por lo que me gustaría que los puntos suspensivos aparezcan a la izquierda. Algo así como este arte ascii:

---------------------------- |first > second > third | |...second > third > fourth| |...fifth > sixth > seventh| ----------------------------

Observe que la primera fila es lo suficientemente corta para que quede alineada a la izquierda, pero las otras dos son demasiado largas, por lo que la elipsis aparece en el lado izquierdo.

Preferiría una solución CSS única, pero JS está bien si no se puede evitar. Está bien si la solución solo funciona en Firefox y Chrome.

EDITAR: en este momento estoy buscando una solución para los errores en Chrome que impiden que se reproduzca correctamente cuando se mezcla un documento RTL y LTR. Eso fue todo lo que realmente necesitaba desde el principio, simplemente no me di cuenta.


¿Qué tal algo así jsFiddle ? Utiliza la dirección, el texto alineado y el desbordamiento de texto para obtener puntos suspensivos a la izquierda. De acuerdo con MDN , puede existir la posibilidad de especificar las elipsis de la izquierda en el futuro con el valor de left-overflow-type pero se considera que todavía es experimental.

p { white-space: nowrap; overflow: hidden; /* "overflow" value must be different from "visible" */ text-overflow: ellipsis; width: 170px; border: 1px solid #999; direction: rtl; text-align: left; }

<p>first > second > third<br /> second > third > fourth > fifth > sixth<br /> fifth > sixth > seventh > eighth > ninth</p>​


Es un poco problemático, pero tal vez un punto en la dirección correcta

http://jsfiddle.net/HerrSerker/ZfbaD/50/

<div class="container"> <span class="part">second</span> <span class="part">&gt;</span> <span class="part">third</span> <span class="part">&gt;</span> <span class="part">fourth</span> <span class="part">&gt;</span> <span class="part">fifth</span> <span class="part">&gt;</span> <span class="part">sixth</span> </div>

​.container { white-space: nowrap; overflow: hidden; /* "overflow" value must be different from "visible" */ text-overflow: ellipsis; width:170px; border:1px solid #999; direction:rtl; } .container .part { direction:ltr; }


Finalmente tuve que crackear y hacer algo en JavaScript. Tenía la esperanza de que alguien presentara una solución CSS de granizo, pero parece que la gente está votando la respuesta que debería ser correcta si no fuera por los errores de Chrome. j08691 puede tener la recompensa por su trabajo .

<html> <head> <style> #container { width: 200px; border: 1px solid blue; } #container div { width: 100%; overflow: hidden; white-space: nowrap; } </style> <script> function trimRows() { var rows = document.getElementById(''container'').childNodes; for (var i=0, row; row = rows[i]; i++) { if (row.scrollWidth > row.offsetWidth) { var textNode = row.firstChild; var value = ''...'' + textNode.nodeValue; do { value = ''...'' + value.substr(4); textNode.nodeValue = value; } while (row.scrollWidth > row.offsetWidth); } } } </script> </head> <body onload=''trimRows();''> <div id="container" > <div>first > second > third</div> <div>second > third > fourth > fifth > sixth</div> <div>fifth > sixth > seventh > eighth > ninth</div>​ </div> </body> </html>

Fiddle


Puse un poco de JavaScript para eliminar tres elementos y agregar los puntos suspensivos en donde sea necesario. Esto no analiza explícitamente cuánto texto encajará en la caja, pero si la caja está arreglada, esto puede no ser un problema.

<style> p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width:170px; border:1px solid #999; direction:rtl; text-align:left; } </style> <p>first &gt; second &gt; third<br /> second &gt; third &gt; fourth &gt; fifth &gt; sixth<br /> fifth &lt; sixth &lt; seventh &lt; eighth &lt; ninth</p> <script> var text = $( ''p'' ).text(), split = text.split( ''/n'' ), finalStr = ''''; for( i in split ){ finalStr = finalStr.length > 0 ? finalStr + ''<br />'' : finalStr; var match = /(/w+/s?(<|>)?/s?){3}$/.exec( split[i] ); finalStr = finalStr + ( split[i].length > match[0].length ? ''...'' : '''' ) + match[0]; } $( ''p'' ).empty().html( finalStr ); </script>


Según tu edición:

En este punto, estoy buscando una solución para los errores en Chrome que impiden que se reproduzca correctamente cuando se mezcla un documento RTL y LTR. Eso fue todo lo que realmente necesitaba desde el principio, simplemente no me di cuenta.

¿Has investigado en la propiedad unicode-bidi css (ver Sitepoint o W3C )? De hecho, me enteré de esto en otra publicación reciente . Supongo que querrías usar el valor de embed para aquellas piezas que van en la dirección opuesta al sitio principal. Entonces en la respuesta de j08691 donde está la direction: rtl agrega unicode-bidi: embed al CSS. Esto debería resolver los problemas de "RTL y RTL mixtos" que está teniendo.


Si no le importa la indexación de esos textos, puede usar este método (invierte las líneas de texto):

Si tiene en sus textos otros elementos HTML además de <br> , necesita hacer algunos arreglos para usar este método.

Código HTML:

<p>first > second > third<br/> second > third > fourth <br> fifth > sixth > seventh</p>

Código CSS:

p{ overflow: hidden; text-overflow: ellipsis; unicode-bidi: bidi-override; direction: rtl; text-align: left; white-space: nowrap; width: 140px; }

Código JavaScript

[].forEach.call(document.getElementsByTagName("p"), function(item) { var str = item.innerText; //Change the operators str = str.replace(/[<>]/g, function(char){ return ({"<" : ">", ">" : "<"})[char] }); //Get lines var lines = str.split(//n/); //Reverse the lines lines = lines.map(function(l){ return l.split("").reverse().join("") }); //Join the lines str = lines.join("<br>"); item.innerHTML = str; });

jsfiddle


Usando @Hemlocks, @Brian Mortenson y las soluciones de @Jimbo, construí un plugin jQuery para resolver este problema.

También he agregado soporte para devolver el valor inicial usando .html () en lugar de tener que devolver el HTMLHTML actual. Espero que sea útil para alguien ...

(function($) { $.trimLeft = function(element, options) { var trim = this; var $element = $(element), // reference to the jQuery version of DOM element element = element; // reference to the actual DOM element var initialText = element.innerHTML; trim.init = function() { overrideNodeMethod("html", function(){ return initialText; }); trimContents(element, element); return trim; }; trim.reset = function(){ element.innerHTML = initialText; return trim; }; //Overide .html() to return initialText. var overrideNodeMethod = function(methodName, action) { var originalVal = $.fn[methodName]; var thisNode = $element; $.fn[methodName] = function() { if (this[0]==thisNode[0]) { return action.apply(this, arguments); } else { return originalVal.apply(this, arguments); } }; }; var trimContents = function(row, node){ while (row.scrollWidth > row.offsetWidth) { var childNode = node.firstChild; if (!childNode) return true; if (childNode.nodeType == document.TEXT_NODE){ trimText(row, node, childNode); } else { var empty = trimContents(row, childNode); if (empty){ node.removeChild(childNode); } } }; }; var trimText = function(row, node, textNode){ var value = ''/u2026'' + textNode.nodeValue; do { value = ''/u2026'' + value.substr(4); textNode.nodeValue = value; if (value == ''/u2026''){ node.removeChild(textNode); return; } } while (row.scrollWidth > row.offsetWidth); }; trim.init(); }; $.fn.trimLeft = (function(options){ var othat = this; var single = function(that){ if (undefined == $(that).data(''trim'')) { var trim = new $.trimLeft(that, options); $(that).data(''trim'', trim); $(window).resize(function(){ $(that).each(function(){ trim.reset().init(); }); }); } }; var multiple = function(){ $(othat).each(function() { single(this); }); }; if($(othat).length>1) multiple(othat); else single(othat); //----------- return this; }); })(jQuery);

Iniciar usando:

//Call on elements with overflow: hidden and white-space: nowrap $(''#container>div'').trimLeft(); //Returns the original innerHTML console.log($(''#test'').html());

fiddle


Usando un marcado un poco más complejo (usando la etiqueta bdi y un lapso adicional para las elipsis), podemos resolver el problema completamente en CSS, sin necesidad de JS en absoluto: navegador cruzado (IE, FF, Chrome) e incluir la puntuación marcas a la derecha:

http://jsbin.com/dodijuwebe/1/edit?html,css,output

Por supuesto, esto es algo así como un truco, que involucra la bondad de los pseudo-elementos. Sin embargo, nuestro equipo ha estado usando este código en producción y no hemos tenido ningún problema en absoluto.

Las únicas advertencias son: la altura de la línea necesita ser reparada y el color de fondo debe conocerse explícitamente (heredar no funcionará).