2016-05-24 15 views
5

Sto creando un sito Web in due colonne, a sinistra, è possibile scrivere e visualizzato a destra con un design speciale.
Il fatto è che vorrei consentire un'interruzione di linea sul lato destro, ma non viene visualizzata. Come potrei farlo?
Ecco un'anteprima del mio disegno. Per vedere l'immagine completa, ecco un >Fiddle HEREConsenti interruzione di riga con javascript + LivePreview

function wordsinblocks(self) { 
     var demo = document.getElementById("demo"), 
     initialText = demo.textContent, 
     wordTags = initialText.split(" ").map(function(word) { 
      return '<span class="word">' + word + '</span>'; 
     }); 

     demo.innerHTML = wordTags.join(''); 
     self.disabled = true; 
     fitWords(); 
     window.addEventListener('resize', fitWords); 
    } 



    $(function() { 
     $('textarea.source').livePreview({ 
     previewElement: $('p#demo'), 
     allowedTags: ['p', 'strong', 'br', 'em', 'strike'], 
     interval: 20 
     }); 
    }); 

    window.onload = wordsinblocks(self); 

    function fitWords() { 
     var demo = document.getElementById("demo"), 
     width = demo.offsetWidth, 
     sizes = [7.69230769230769, 23.07692307692307, 46.15384615384614, 100], 
     calculated = sizes.map(function(size) { 
      return width * size/100 
     }), 
     node, 
     i, 
     nodeWidth, 
     match, 
     index; 


     for (i = 0; i < demo.childNodes.length; i++) { 
     node = demo.childNodes[i]; 
     node.classList.remove('size-1', 'size-2', 'size-3', 'size-4'); 

     nodeWidth = node.clientWidth; 
     match = calculated.filter(function(grid) { 
      return grid >= nodeWidth; 
     })[0]; 
     index = calculated.indexOf(match); 


     node.classList.add('size-' + (index + 1)); 
     } 
    } 
+0

Se si digita un'interruzione di riga HTML
a sinistra, viene visualizzata nell'anteprima. – kizeloo

+0

Non sul mio. http://www.o-y-o.fr/simon/goo.jpg. Ma mi piacerebbe evitare la scrittura HTML :) – Yagayente

+0

Provalo con maiuscolo
e nessuno spazio tra, e lo sarà. Non ti aiuta comunque, tranne che per cercare di rintracciare il problema, forse. – kizeloo

risposta

4

è necessario dividere la fonte (quello che si scrive) di new line e poi dividere ogni riga da space.

Aggiornamento wordsinblocks come:

function wordsinblocks(self) { 
    var demo = document.getElementById("demo"), 
    initialText = demo.innerText, 
    wordTags = initialText.split(/\n/g).map(function(line) { 
     var spanWord = line.split(/\s/g).filter(Boolean).map(function(word){ 
      return '<span class="word">' + word + '</span>'; 
     }); 

     return "<span class='line-break'>" + spanWord.join("") + "</span>"; 
    }); 

    demo.innerHTML = wordTags.join(''); 

    self.disabled = true; 
    fitWords(); 
    window.addEventListener('resize', fitWords); 
} 

Aggiornamento fitWords come

function fitWords() { 
    var demo = document.getElementById("demo"), 
    width = demo.offsetWidth, 
    sizes = [7.69230769230769, 23.07692307692307, 46.15384615384614, 100], 
    calculated = sizes.map(function(size) { 
     return width * size/100 
    }), 
    lineNode, 
    node, 
    i, k, 
    nodeWidth, 
    match, 
    index; 

    for (k = 0; k < demo.childNodes.length; k++) { 
    lineNode = demo.childNodes[k]; 
    for(i = 0; i < lineNode.childNodes.length; i++) { 
     node = lineNode.childNodes[i]; 
     node.classList.remove('size-1', 'size-2', 'size-3', 'size-4'); 

     nodeWidth = node.clientWidth; 
     match = calculated.filter(function(grid) { 
      return grid >= nodeWidth; 
     })[0]; 
     index = calculated.indexOf(match); 

     node.classList.add('size-' + (index + 1)); 
    } 
    } 
} 

Add seguenti style nel vostro css

#demo .line-break:after { 
    clear: both; 
    display: table; 
    content: "" 
} 

FIDDLE DEMO HERE

Spero, ti aiuta & fammi sapere se mi manca qualcosa.

UPDATE per più linea-Break

Aggiornamento textarea.reloadPreview come

textarea.reloadPreview = function() { 
    var previewString = this.val().replace(/\n/g,"<br>"); 
    if (previewString.length > 0) { 
     previewString = this.htmlUnencode(previewString); 
     previewString = previewString.replace(opts.paraRegExp, "<p>$1</p><p>$2</p>"); 
     previewString = previewString.replace(opts.lineBreakRegExp, "$1<br />$2"); 
     previewString = previewString.replace(allowedTagsRegExp, "<$1>"); 

    } 

    try { 
     // Workaround for a bug in jquery 1.3.2 which is fixed in 1.4 
     preview[0].innerHTML = previewString; 
    } 
    catch (e) { 
     alert("Sorry, but inserting a block element within is not allowed here."); 
    } 

    preview.updatingPreview = false; 
    this.bind('keyup', this.handleKeyUp); 
    wordsinblocks(self); 
} 

Aggiornamento worksinblocks come

function wordsinblocks(self) { 
    var demo = document.getElementById("demo"), 
    initialText = demo.innerText, 
    wordTags = initialText.split(/\n/g).map(function(line) { 
     var spanWord = line.split(/\s/g).filter(Boolean).map(function(word){ 
      return '<span class="word">' + word + '</span>'; 
     }); 

     var result = spanWord.join(""); 
     result = result == "" ? "<span class='empty'></span>" : result; 

     return "<span class='line-break'>" + result + "</span>"; 
    }); 

    demo.innerHTML = wordTags.join(''); 

    self.disabled = true; 
    fitWords(); 
    window.addEventListener('resize', fitWords); 
} 

Add seguente styles nella vostra cs s

#demo .line-break .empty { 
    height: 25px; 
    display: block 
} 

#demo .word { 
    float: left; 
    box-sizing: border-box; 
    -webkit-box-sizing: border-box; 
    -moz-box-sizing: border-box; 
    box-sizing: border-box; 
    padding: 5px; 
    padding-left: 10px; 
    padding-right: 10px; 
    font-size: 2.9vw; 
    height: 25px; 
    font-family: "helvetica"; 
    border: 1px solid black; 
} 

UPDATED FIDDLE HERE

+0

Questa soluzione è anche quasi buona , manca solo la pausa in doppia linea! – Yagayente

+0

@Simtwo, puoi dare un'occhiata a: https://jsfiddle.net/y340tLnb/ –

+0

ok buona prova! Hai ancora bug, guarda lo screenshot del tuo violino: http://www.o-y-o.fr/simon/gof.jpg - sembra che un'interruzione di riga possa apparire all'improvviso alla fine di una "linea" – Yagayente

3

si può fare con i CSS invece white-space: pre;

p { 
    white-space: pre; 
} 
+0

Ho, grazie. L'ho provato, non sembra che risolva il problema, vedi qui: https://jsfiddle.net/yagayente/z0u6gtbL/4/ – Yagayente

5

Si può fare l'inserimento di interruzione di linea ogni volta che si preme il tasto Enter. Un modo è quello di utilizzare .which o .keyCode:

$(document).keydown(function(e){ 
    var event = e.which || e.keyCode; 
    if (event == 13){ 
      //do something like this 
      return '<span class="word"><br/>' + word + '</span>'; 
    } 
}); 

"13" è il codice carattere per Enter. L'ho provato nel tuo codice e funziona perfettamente. Hai solo bisogno di metterlo (alterarlo anche) dove non influisce su nessuno dei tuoi codici di funzionamento.

secondo modo è quello di copiare esattamente ciò che si trova nel pannello "Scrivi" prima di fare alcune azioni, come separare le parole da loro incapsulamento in diversi punti salienti, ecc


[UPDATE # 1]

Solo un pezzo del codice per il test.

function wordsinblocks(self) { 
     var demo = document.getElementById("demo"), 
     initialText = demo.textContent, 
     wordTags = initialText.split(" ").map(function(word) { 
      return '<span class="word">' + word + '</span>'; 
     }); 

     $(document).keydown(function(e){ 
      var event = e.which || e.keyCode; 
      if (event == 13){ 
       demo.innerHTML = wordTags.join(' <br/> '); 
      } else{ 
       demo.innerHTML = wordTags.join(''); 
      } 
     }); 

     self.disabled = true; 
     fitWords(); 
     window.addEventListener('resize', fitWords); 
} 

[UPDATE # 2]

function wordsinblocks(self) { 
     var demo = document.getElementById("demo"), 
     initialText = demo.innerText.replace(/\n\r?/g,"<br/>"), 
     wordTags = initialText.split(" ").map(function(word) { 
      return '<span class="word">' + word + '</span>'; 
     }); 

     demo.innerHTML = wordTags.join(''); 
     self.disabled = true; 
     fitWords(); 
     window.addEventListener('resize', fitWords); 
} 
+1

Ok rhavendc suona perfetto, capisco dove mi porti, ma non riesco a trovare dove mettilo ... potresti darmi una mano sul violino? Ecco il mio ultimo: https://jsfiddle.net/yagayente/z0u6gtbL/9/ – Yagayente

+1

@Simtwo Nei miei test, l'ho inserito nella tua 'function wordsinblocks (self) {...}' e ho fatto un piccolo alter (cercando di non cambiare i codici e la logica) e funziona bene, ma la formattazione non funziona correttamente (il che credo che 'fitWords()' faccia). Ho provato di nuovo un altro alter piccolo e funziona bene, ma il lavoro di 'fitWords()' lampeggia (Vedi l'aggiornamento sopra). Immagino che le parole nel pannello "Scrivi" vengano ripetutamente visualizzate quando si verifica un cambiamento (come il funzionamento di 'onload()). Spetta a te se vuoi apportare alcune modifiche alla logica in modo da poter ottenere gli interruzioni di riga desiderati. – rhavendc

+1

Grazie per il vostro aiuto :) Appena provato: immagino che il "keydown" stia causando problemi, il migliore sarebbe "keyup", immagino? ma non risolve ancora la mia domanda iniziale, perché non voglio perdere il disegno in blocchi: http://oyo.fr/simon/testing2.jpg
quindi suppongo che dovrei cambiare la logica del codice come tu dici, ma io non vedo come, vero? – Yagayente

3

Nizza piccola sfida. Per ottenere una bella forma e gestire le interruzioni di riga textarea:

  • assicurarsi che il testo visualizzato ha la stessa formattazione nella textarea: altezza della linea, la larghezza, spaziatura tra lettere, dimensioni ....
  • Sostituire nuove linee con un <br /> ->/(?:\r\n|\r|\n)/g
  • Usa blocchi singoli per gli spazi -> si accerterà che vengano visualizzati doppi spazi bianchi e spazi bianchi all'inizio di una linea.

Ecco il mio approccio: Fiddle Demo

$(function(){ 
 

 
\t \t var set = { 
 
    \t hookTo : ".leftside textarea", 
 
     dispIn : ".rightside .content", 
 
     newline : "@#@" 
 
    }; 
 
\t \t //Focus text area: 
 
    $(set.hookTo).focus(); 
 
    $(set.hookTo).keyup(function(){ 
 
    \t \t $text = $(this); 
 
     $tar = $(set.dispIn); 
 
     raw = $text.val(); 
 
     box = []; 
 
     //Recplace tags: 
 
     raw.replace(/&/g, "&amp;") 
 
      .replace(/>/g, "&gt;") 
 
      .replace(/</g, "&lt;") 
 
      .replace(/"/g, "&quot;"); 
 
     //Hadle Line breaks: 
 
     raw = raw.replace(/(?:\r\n|\r|\n)/g, set.newline); 
 
     //Boxes: 
 
     box = raw.split(' '); 
 
     $.each(box, function(i,e){ 
 
     \t var newlines; 
 
     \t if (e === "") { 
 
      box[i] = "<div class='wordbox space'>&nbsp;</div>"; 
 
      } else { 
 
      \t newlines = e.split(set.newline); 
 
      if (newlines.length > 0) { 
 
      \t $.each(newlines,function(index,el) { 
 
       \t \t if (el === "") 
 
        \t newlines[index] = "<div class='wordbox space'>&nbsp;</div>"; 
 
        else 
 
        newlines[index] = "<div class='wordbox'>" + el + "</div>" 
 
         + "<div class='wordbox space'>&nbsp;</div>"; 
 
       }); 
 
       box[i] = newlines.join("<br />"); 
 
      } else { 
 
      \t box[i] = "<div class='wordbox'>" + e + "</div>" 
 
      \t \t \t \t \t + "<div class='wordbox space'>&nbsp;</div>"; 
 
      } 
 
      } 
 
     }); 
 
     $tar.html(box.join("")); 
 
    }); 
 
});
body { background-color:white; height:100%; } 
 
.wrapper { width:100%; font-size:0; box-sizing:border-box; } 
 
.leftside, 
 
.rightside { 
 
    width:50%; 
 
    display:inline-block; 
 
    font-size:16px; 
 
    vertical-align: top; 
 
    font-family:arial; 
 
} 
 
.rightside .header, 
 
.leftside .header { 
 
    font-size:16px; 
 
    padding:10px 20px; 
 
    font-weight:bold; 
 
} 
 
.rightside .header { 
 
    color: black; 
 
    background-color:orange; 
 
} 
 
.leftside .header { 
 
    color: orange; 
 
    background-color:black; 
 
} 
 
.rightside .content { 
 
    width:100%; 
 
    padding:10px 20px; 
 
    box-sizing:border-box; 
 
    font-size:0; 
 
} 
 
.rightside .content .wordbox { 
 
    outline: 1px solid black; 
 
    line-height:16px; 
 
    letter-spacing: 1px; 
 
    font-size:15px; 
 
    display:inline-block; 
 
    margin-bottom: 3px; 
 
} 
 
.rightside .content .wordbox.space { 
 
    outline: 0; 
 
    opacity:0; 
 
} 
 
.wrapper textarea { 
 
    \t width:100%; 
 
    \t box-sizing:border-box; 
 
    border:0; 
 
    \t overflow: auto; 
 
    outline: none; 
 
    -webkit-box-shadow: none; 
 
    -moz-box-shadow: none; 
 
    box-shadow: none; 
 
    resize: none; 
 
    padding:10px 20px; 
 
    font-size:15px; 
 
    font-family:arial; 
 
    line-height:16px; 
 
    letter-spacing: 1px; 
 
    min-height:400px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<div class="wrapper"> 
 
\t <div class="leftside"> 
 
     <div class="header">Write</div> 
 
     <textarea placeholder="Type here please"></textarea> 
 
    </div> 
 
    <div class="rightside"> 
 
     <div class="header">See</div> 
 
     <div class="content"></div> 
 
    </div> 
 
</div>

+0

Questa soluzione sembra essere la più vicina perché consente di effettuare doppie interruzioni di riga, ma non carica il dimensionamento delle scatole! Quasi lì ! – Yagayente

+0

Cosa intendi con "il dimensionamento delle scatole"? –

+0

vedere questo https://jsfiddle.net/z0u6gtbL/3/ Ogni parola è posta in scatole (span) in base alla dimensione della parola (la funzione "wordsinblocks" che è nella domanda) – Yagayente

3

Il corto, soluzione hacky

Change wordsinblocks a

function wordsinblocks(self) { 
    var demo = document.getElementById("demo"), 
    initialText = demo.textContent.replace(new RegExp("\n", "g"), '<br>'), 
    wordTags = initialText.split(" ").map(function(wordWithLineBreaks) { 
     return wordWithLineBreaks.split('<br>').map(function(word, index, arr) { 
      return (word === '' ? '' : '<span class="word">' + word + '</span>') + 
     (index < arr.length - 1 ? '<div class="lb">&nbsp;</div>' : '') ; 
     }).join(''); 
    }); 

    demo.innerHTML = wordTags.join(''); 
    self.disabled = true; 
    fitWords(); 
    window.addEventListener('resize', fitWords); 
} 

Nel for ciclo all'interno della funzione fitWords, aggiungere, dopo la prima riga del loop :

if (node.tagName.toLowerCase() === 'div') continue; 

Change

$(function() { 
    $('textarea.source').livePreview({ 
    previewElement: $('p#demo'), 
    allowedTags: ['p', 'strong', 'br', 'em', 'strike'], 
    interval: 20 
    }); 
}); 

a

$(function() { 
    $('textarea.source').livePreview({ 
    previewElement: $('p#demo'), 
    allowedTags: [], 
    paraRegExp: new RegExp('something nobody will ever enter'), 
    lineBreakRegExp: new RegExp('something nobody will ever enter'), 
    interval: 20 
    }); 
}); 

aggiungere alla fine del tuo css:

.lb { 
    display: block; 
    clear: both; 
} 

Vedi jsfiddle per soluzione completa.

Alcune riflessioni circa la soluzione

Anche se, questa soluzione funziona, è tutt'altro che ottimale.

Ad esempio, l'utilizzo del plugin livePreview jQuery non ha molto senso perché sembra che non hai bisogno di supporto HTML come il codice utilizza la proprietà textContent dopo livePreview ha fatto il suo lavoro, che rimuove efficacemente tutti HTML.

Questo è anche il motivo per cui l'inserimento delle interruzioni di riga (aggiunte premendo il tasto Invio) non ha funzionato nel codice originale. Quello che è successo è stata la seguente: entra

  • utente del testo con interruzioni di linea
  • livePreview sostituisce queste interruzioni di riga con <br> dovuto l'uso dell'opzione lineBreakRegExp.
  • la proprietà textContent restituisce solo il testo, il che significa che gli <br> si sono persi di nuovo.

Quindi, in realtà, @Shlomi Hassid ha fornito un approccio migliore, ancora incompleto. Incompleto perché manca il dimensionamento delle scatole.

Problemi correlati