javascript - code - detectar saltos de línea con jQuery?
remove line breaks javascript (7)
¿es posible que jQuery / javascript detecte dónde se rompe una cadena (para ajustarse a las restricciones de ancho de CSS) para insertar elementos DOM antes del comienzo de una nueva línea?
Alternativamente, puede comparar el ancho del bloque de texto con el ancho de su padre. Si el bloque es al menos el 98% del ancho de su elemento primario, bastante seguro de que se rompe
Aquí hay un enfoque. Nota: No veo una solución ideal sin usar fuentes monoespaciales. El igual con los personajes hace que esta tarea sea mucho más fácil.
- Caracteres de ancho igual
- Calcule el tamaño de un personaje
- Calcule el tamaño del contenedor
- Encuentra personajes por fila
- Encuentra dónde se romperá la fila (es decir, espacios en blanco, guiones, etc.)
- Obtener todos los índices de ruptura.
Eche un vistazo al jsfiddle para html asociado. No he completado esta función. Se deben agregar más comprobaciones al calcular el índice de ruptura. En este momento está usando lastIndexOf (''''), pero esto ignora que el siguiente índice podría ser un espacio, o el actual. Además, no estoy teniendo en cuenta otros personajes de salto de línea. Sin embargo, este debería ser un gran punto de partida.
var text = $(''#text'').text(), // "lorem ipsum ... "
len = text.length, // total chars
width = $(''#text'').width(), // container width
span = $(''<span />'').append(''a'').appendTo(''#sandbox''),
charWidth = span.width(), // add single character to span and test width
charsPerRow = Math.floor(width/charWidth); // total characters that can fit in one row
var breakingIndexes = [], // will contain indexes of all soft-breaks
gRowStart = 0, // global row start index
gRowEnd = charsPerRow;// global row end index
while(gRowEnd < len){
var rowEnd = text.substring(gRowStart, gRowEnd).lastIndexOf('' ''); // add more checks for break conditions here
breakingIndexes.push(gRowStart + rowEnd); // add breaking index to array
gRowStart = gRowStart + rowEnd + 1; // next start is the next char
gRowEnd = gRowStart + charsPerRow; // global end inxex is start + charsperrow
}
var text2 = $(''#text2'').text(); // "lorem ipsum ... " now not width bound
var start = 0, newText = '''';
for(var i=0; i < breakingIndexes.length; i++){
newText += text2.substring(start, breakingIndexes[i]) + ''<br />''; // add hard breaks
start = breakingIndexes[i]; // update start
}
$(''#text2'').html(newText); // output with breaks
Creo que sería más fácil de detectar usando una expresión regular, mucho menos código y al mismo tiempo conservando la eficiencia.
Aquí hay algo que funcionó para mí:
if ((/(/r/n|/n|/r)/.test($(this).val()))) {
alert(''there are line breaks here'')
}
No estoy seguro de si esto funcionará con sus cadenas rotas, pero funciona para detectar breves líneas con jQuery.
No estoy seguro de cuál es exactamente su caso de uso, pero http://code.google.com/p/hyphenator/ puede ser una solución a su problema o si profundiza en el código fuente de hyphenator.js, es posible que pueda encontrar el código Estás buscando.
No sé de ninguna jQuery incorporada de la función javascript para hacer esto. Sin embargo, podría hacerlo usted mismo, pero sería potencialmente lento si tiene mucho texto.
En teoría, puede asegurarse de que la altura esté configurada en automático, eliminar el texto y luego, palabra por palabra, reinsertarlo. En un cambio en la altura, eliminas la última palabra e insertas tu elemento dom. De nuevo, esto será lento si hay mucho texto, y la mejor manera de hacerlo sería no cambiar el elemento original, sino hacerlo en otro elemento que podría estar oculto, y luego reemplazar el elemento original al finalizar. De esta forma, su usuario no vería desaparecer el contenido y luego volvería palabra por palabra.
Otra forma sería usar un principio similar, y comenzar con un elemento vacío del mismo tamaño con altura automática, e insertar un nuevo carácter y un espacio hasta que obtenga una nueva línea. A partir de ahí, puede usar esto como una aproximación con la técnica anterior, o puede sumar ciegamente la longitud de cada cuerda hasta que encuentre una nueva línea, teniendo en cuenta el ancho de su elemento dom. Sin embargo, esta técnica funciona mejor con fuentes monoespaciadas, que es donde se usa solo cuando entra una aproximación.
Dicho esto, hay una manera de medir el texto utilizando canvas, pero eso puede ser extremo. En teoría sería, crear un elemento canvas, obtener el contexto, establecer todas las propiedades de la fuente y luego usar el método context.measureText()
. Un ejemplo de su uso se puede encontrar here .
Se me ocurrió un enfoque, pero podría ser excesivo para tus propósitos, así que ten esto en cuenta.
Debe crear un clon del elemento, vaciar el original y luego volver a mover cada palabra al elemento original. Si la altura cambia en cualquier punto, hay un salto de línea antes de esa palabra. Esto sería bastante fácil de hacer usando $(el).text()
, pero se vuelve más complicado si puede haber otras etiquetas adentro, no solo texto. Intenté explicar cómo descomponerlo por nodo en este cuadro de respuesta, pero me resultó más fácil simplemente crear un complemento jQuery en jsFiddle. Enlace aquí: http://jsfiddle.net/nathan/qkmse/ ( Gist ).
No manejará bien los elementos flotantes, y hay algunas otras situaciones en las que se caerá. Avíseme si desea obtener más opciones, o si no funciona para sus fines, o si no está seguro de cómo aplicarlo y trataré de ayudarlo.
este es mi script, que toma texto, y luego hace que cada línea sea un lapso
CSS:
margin: 0;
padding: 0;
}
.title{
width: 300px;
background-color: rgba(233,233,233,0.5);
line-height: 20px;
}
span{
color: white;
background-color: red;
display: inline-block;
font-size: 30px;
}
a{
text-decoration: none;
color: black;
}
html
<div class="title">
<a href="">SOME TEXT LONG TEXT ANDTHISISLONG AND THIS OTHER TEXT</a>
</div>
JS
$(function(){
$(".title").find("a").each(function(){
var $this = $(this);
var originalText = $this.text();
$this.empty();
var sections = [];
$.each( originalText.split(" "), function(){
var $span = $("<span>" + this + "</span>");
$this.append($span);
var index = $span.position().top;
if( sections[index] === undefined ){
sections[index] = "";
}
sections[index] += $span.text() + " ";
});
$this.empty();
for(var i = 0; i< sections.length; i++){
if( sections[i] !== undefined ){
var spanText = $.trim(sections[i]);
$this.append("<span>" + spanText + "</span>");
}
}
});
});
Tienes que incluir jQuery.