Posso racchiudere ogni linea di testo su più righe in un intervallo?

Ho cercato di capire come farlo (se è anche ansible) e ho disegnato un vuoto …

Ho del testo che si avvolgerà su più righe. Voglio rilevare ogni singola linea e avvolgerla in un intervallo. Infine, voglio assegnare una class a ogni intervallo da un array di loop.

Per esempio…!

I have some text that wraps onto three lines in this container

Voglio che il mio jQuery analizzi quelle linee, rilevi dove si trova e lo trasformi in questo:

 
I have some text that wraps onto three lines in this container

La ragione per cui voglio farlo dynamicmente è che lo sto facendo all’interno di modelli reattivi, quindi a volte lo stesso testo si avvolge solo su due righe, o forse quattro in un iPhone.

È fattibile? Ho trovato questo -> http://vidasp.net/tinydemos/numberOfLines.html che calcola il numero di linee utilizzate in un blocco di testo, ma che non si estende in realtà per fare ciò di cui ho bisogno.

Se qualche ninja jquery può essere d’aiuto, sarei molto grato!

Sembra che tu stia chiedendo come dividere il testo dove viene naturalmente spostato dal browser. Sfortunatamente, questo non è affatto semplice. Né è robusto – si consideri il seguente scenario:

  • L’utente sfoglia la tua pagina, il div è reso e l’evento onload si triggers,
  • 3 elementi di span vengono creati dal nodo di testo, 1 per ogni riga di testo avvolta,
  • L’utente ridimensiona il browser e la dimensione delle modifiche div.

Il risultato è che gli span non sono più correlati a dove iniziano e finiscono le linee. Ovviamente, questo scenario è evitabile usando elementi a larghezza fissa o puoi rejigare tutto quando il browser ridimensiona, ma questo è solo un esempio di come si può rompere.

Tuttavia, non è facile. Una domanda simile è già emersa (anche se con un objective diverso) e sono apparse due soluzioni, che potrebbero essere utili qui:

Soluzione 1: getClientRects ()

In realtà non avvolgere il testo in intervalli, ma ottenere la posizione e le dimensioni di ogni riga di testo utilizzando getClientRects() . Quindi, crea il numero di span necessari e posizionali / ridimensionali dietro ogni riga di testo.

Professionisti

  • Veloce; getClientRects restituisce la posizione di ogni riga
  • Semplice; il codice è più elegante della soluzione 2

Contro

  • Il testo avvolto deve essere contenuto da un elemento in linea.
  • Nessuno stile si applica effettivamente al testo (come il peso del font o il colore del font). Utile solo per cose come il colore di sfondo o il bordo.

La demo fornita con la risposta mostra come è ansible evidenziare la linea di testo attualmente sotto il mouse.

Soluzione 2: divisione, unione, loop, unione

Suddividere il testo in una matrice usando il metodo split () con un limite di parola o uno spazio bianco come argomento passato. Riunisci l’array in una stringa con tra ogni elemento e avvolgi il tutto con e e sostituisci il nodo di testo originale con l’HTML risultante nell’elemento contenitore. Ora, scorrere su ciascuno di questi elementi di span controllando la sua posizione y all’interno del contenitore. Quando la posizione y aumenta, sai di aver raggiunto una nuova riga e che gli elementi precedenti possono essere uniti in un’unica span.

Professionisti

  • Ogni linea può essere abbinata a qualsiasi proprietà CSS, come il peso dei font o la decorazione del testo.
  • Ogni riga può avere i propri gestori di eventi.

Contro

  • Lento e ingombrante a causa delle numerose operazioni DOM e di stringa

Conclusione

Ci possono essere altri modi per raggiungere il tuo objective, ma non sono sicuro di me stesso. TextNode.splitText(n) può dividere un TextNode in twain (!) Quando viene passato un indice numerico del carattere su cui vuoi dividere. Nessuna delle soluzioni di cui sopra è perfetta ed entrambe si interrompono non appena l’elemento di contenimento viene ridimensionato.

Ho messo insieme un violino che implementa la soluzione n. 2 di Andy E (sopra). Spaccati, unisciti, fai un loop, unisci

Ecco l’algoritmo:

 var spanInserted = $('#someText').html().split(" ").join(" "); var wrapped = ("").concat(spanInserted, ""); $('#someText').html(wrapped); var refPos = $('#someText span:first-child').position().top; var newPos; $('#someText span').each(function(index) { newPos = $(this).position().top if (index == 0){ return; } if (newPos == refPos){ $(this).prepend($(this).prev().text() + " "); $(this).prev().remove(); } refPos = newPos; }); 

Godere…

 var classs = ",red-bg,orange-bg,yellow-bg".split(",") var txt = $('#quote').html().split("\n") //this gives you FIVE items because of the leading and trailing CRs //so we skip the first and last item in the loop var output = "" for(var x=1;x"+txt[x]+"" } $('#quote').html(output) 

Questo ti porterà il nodo del testo ma non sono sicuro che sia d’aiuto

 $("#quote") .contents() .filter(function() { return this.nodeType == 3; })