rilevare interruzioni di riga con jQuery?

è ansible avere jQuery / javascript rilevare dove una stringa è rotta (per adattarsi ai vincoli di larghezza CSS) in modo da inserire elementi DOM prima dell’inizio di una nuova riga?

Ho trovato un approccio, ma potrebbe essere eccessivo per i vostri scopi, quindi tenetelo in considerazione.

Devi creare un clone dell’elemento, svuotare l’originale, quindi spostare ogni parola nell’elemento originale. Se l’altezza cambia in qualsiasi punto, c’è una interruzione di linea prima di quella parola. Questo sarebbe abbastanza semplice da usare con $(el).text() , ma diventa più complicato se ci possono essere altri tag all’interno, non solo testo. Ho provato a spiegare come suddividerlo per nodo in questa finestra di risposta, ma ho trovato più semplice creare un plugin jQuery in un jsFiddle. Link qui: http://jsfiddle.net/nathan/qkmse/ ( Gist ).

Non gestirà bene gli elementi fluttuanti, e ci sono alcune altre situazioni in cui cadrà. Fammi sapere se desideri avere più opzioni o se non funziona per i tuoi scopi, o se non sei sicuro di come applicarlo e cercherò di aiutarti.

Ecco un approccio. Nota: non vedo una soluzione ideale senza utilizzare i font monospace. La parità con i personaggi rende questo compito molto più semplice.

  1. Caratteri di larghezza uguale
  2. Calcola la dimensione di un personaggio
  3. Calcola la dimensione del contenitore
  4. Trova personaggi per riga
  5. Trova dove si romperà la riga (cioè spazi bianchi, trattini, ecc.)
  6. Ottieni tutti gli indici di rottura.

Dai un’occhiata al jsfiddle per l’html associato. Non ho completato questa funzione. Ulteriori controlli devono essere inseriti nel calcolo dell’indice di rottura. In questo momento sta usando lastIndexOf (”), ma questo ignora che il prossimo indice potrebbe essere uno spazio, o la corrente. Inoltre non sto tenendo conto di altri personaggi che rompono le righe. Tuttavia questo dovrebbe essere un ottimo punto di partenza.

 var text = $('#text').text(), // "lorem ipsum ... " len = text.length, // total chars width = $('#text').width(), // container width 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]) + '
'; // add hard breaks start = breakingIndexes[i]; // update start } $('#text2').html(newText); // output with breaks

http://jsfiddle.net/Y5Ftn/1/

questo è il mio script, che prende il testo e quindi rende ogni riga di span

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

  

JS

 $(function(){ $(".title").find("a").each(function(){ var $this = $(this); var originalText = $this.text(); $this.empty(); var sections = []; $.each( originalText.split(" "), function(){ var $span = $("" + this + ""); $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("" + spanText + ""); } } }); }); 

Devi avere jQuery incluso.

Non conosco alcun jQuery incorporato nella funzione javascript per farlo. Potresti, comunque, farlo da solo, ma sarebbe potenzialmente lento se hai un sacco di testo.

In teoria, puoi assicurarti che l’altezza sia impostata su auto, rimuovere il testo e poi reinserirla parola per parola. In caso di modifica dell’altezza, rimuovi l’ultima parola e inserisci l’elemento dom. Di nuovo, questo sarà lento se c’è molto testo, e il modo migliore per farlo sarebbe quello di non cambiare l’elemento originale, ma farlo in un altro elemento che potrebbe essere nascosto, e quindi sostituire l’elemento originale al completamento. In questo modo, il tuo utente non vedrebbe il contenuto scomparire e quindi tornare indietro parola per parola.

Un altro modo sarebbe utilizzare un principio simile, e iniziare con un elemento vuoto della stessa dimensione con altezza automatica, e inserire un nuovo carattere e uno spazio finché non si ottiene una nuova linea. Da lì, puoi usarlo come un’approssimazione con la tecnica precedente, oppure puoi aggiungere ciecamente la lunghezza di ogni stringa finché non trovi una nuova linea, tenendo conto della larghezza del tuo elemento dom. Questa tecnica funziona meglio con i caratteri monospaziati, che è dove si usa solo quando arriva un’approssimazione.

Detto questo, c’è un modo per misurare il testo usando la canvas, ma potrebbe essere estremo. In teoria sarebbe, creare un elemento canvas, ottenere il contesto, impostare tutte le proprietà del font e quindi utilizzare il metodo context.measureText() . Un esempio di utilizzo può essere trovato qui .

Non sei sicuro di quale sia esattamente il tuo caso d’uso, ma http://code.google.com/p/hyphenator/ potrebbe essere una soluzione al tuo problema o se riesci a scavare nel codice sorgente hyphenator.js, potresti riuscire a trovare il codice stai cercando.

Penso che sarebbe più facile rilevare usando un regex – molto meno codice pur mantenendo l’efficienza.

Ecco qualcosa che ha funzionato per me:

 if ((/(\r\n|\n|\r)/.test($(this).val()))) { alert('there are line breaks here') } 

Non sono sicuro che funzionerà con le stringhe spezzate, ma funziona per rilevare i line-breks con jQuery.

In alternativa puoi confrontare la larghezza del blocco di testo con la larghezza del suo genitore. Se il blocco è almeno il 98% della larghezza del suo genitore, è piuttosto sicuro che si rompa