2010-05-20 18 views
22

Sto utilizzando un 'contenteditable' <div/> e abilitando PASTE.Pulisci testo incollato con Microsoft Word utilizzando JavaScript

È sorprendente la quantità di codice di markup che viene incollato da una copia di appunti da Microsoft Word. Sto combattendo questo, e ho ottenuto circa 1/2 modo lì usando la funzione stripTags() dei Prototipi (che sfortunatamente non sembra permettermi di tenere alcuni tag).

Tuttavia, anche in seguito, mi ritrovo con una quantità incredibile di codice di markup non necessario.

Quindi la mia domanda è, c'è qualche funzione (utilizzando JavaScript), o un approccio che posso usare che ripulirà la maggior parte di questo markup non necessario?

+0

meglio di fortuna con questo ... il contenuto generato da Word (sia in incollare, e salvare come lascia HTML molto a desiderare) ;-) – scunliffe

+0

ho chiesto più o meno la stessa domanda allora http://stackoverflow.com/questions/391291/how-do-i-remove-word-markup-crap-when-inserting-to-a-form, ma il tuo titolo è migliore. Tuttavia, perché limitarti a javascript e non considerare di farlo sul server? –

risposta

18

Ecco la funzione in cui ho terminato la scrittura che svolge il lavoro abbastanza bene (per quanto posso dire in ogni caso).

Sono certamente aperto a suggerimenti di miglioramento se qualcuno ne ha. Grazie.

function cleanWordPaste(in_word_text) { 
var tmp = document.createElement("DIV"); 
tmp.innerHTML = in_word_text; 
var newString = tmp.textContent||tmp.innerText; 
// this next piece converts line breaks into break tags 
// and removes the seemingly endless crap code 
newString = newString.replace(/\n\n/g, "<br />").replace(/.*<!--.*-->/g,""); 
// this next piece removes any break tags (up to 10) at beginning 
for (i=0; i<10; i++) { 
    if (newString.substr(0,6)=="<br />") { 
    newString = newString.replace("<br />", ""); 
    } 
} 
return newString; 
} 

Spero che questo sia utile per alcuni di voi.

2

Che ne dici di avere un pulsante "incolla come testo normale" che visualizza un <textarea>, che consente all'utente di incollare il testo lì dentro? in questo modo, tutti i tag verranno spogliati per te. Questo è quello che faccio con il mio CMS; Ho rinunciato a cercare di ripulire il caos di Word.

+0

Questo sarebbe il mio caso peggiore, suppongo (e il modo in cui sembra, potrebbe essere l'unico scenario - molto deprimente). – OneNerd

+0

@OneNerd: ho contrassegnato la tua domanda come preferita perché se qualcun altro ha una soluzione migliore penso che la userò anche io! – Josh

+0

mi è venuta in mente qualcosa che * penso * potrebbe essere utilizzabile - vedi la mia risposta (e migliorala anche plz) se vuoi. Grazie - – OneNerd

3

È possibile utilizzare l'intero CKEditor che pulisce su incolla o look at the source.

+0

qualsiasi idea in cui risiede esattamente la funzione (quale file)? – OneNerd

+2

inizia da * .. \ fckeditor \ editor \ _source \ commandclasses \ fckpastewordcommand.js * e cammina all'indietro. –

-1

Potresti incollare in un'area di testo nascosta, copiare dalla stessa area di testo e incollare sulla destinazione?

+0

hmm - beh, sai un modo per inviare il contenuto incollato ad una textarea in modo che sia effettivamente un testo normale invece del codice di markup - poiché la pressione del tasto è sul DIV, posso leggere il contenuto e passarlo alla textarea , ma non sarebbe testo in chiaro. – OneNerd

+0

Penso che lasciare la roba come solo testo non sia la soluzione migliore. Il formato è importante Lavoro in un'applicazione che i miei clienti non vogliono che gli stili di Word vengano rimossi. –

-4

Odio dirlo, ma alla fine ho rinunciato a fare in modo che TinyMCE maneggi le parole cagate come voglio io. Ora ho appena ricevuto un'e-mail ogni volta che l'input di un utente contiene un determinato codice HTML (ad esempio, cerca <span lang="en-US">) e lo correggo manualmente.

+3

Yikes - non è davvero un'opzione per me. – OneNerd

+0

Questa è davvero una buona idea finché l'applicazione non ha più di 0 utenti. –

0

Ho fatto qualcosa del genere molto tempo fa, dove ho completamente ripulito il materiale in un editor di testo avanzato e convertito i tag dei font in stili, da brs a p, ecc., Per mantenerlo consistente tra i browser e impedire che certe cose brutte diventassero in via incolla. Ho preso la mia funzione ricorsiva e ne ho eliminato la maggior parte tranne la logica di base, questo potrebbe essere un buon punto di partenza ("risultato" è un oggetto che accumula il risultato, che probabilmente richiede un secondo passaggio per convertire in una stringa), se questo è quello che vi serve:

var cleanDom = function(result, n) { 
var nn = n.nodeName; 
if(nn=="#text") { 
    var text = n.nodeValue; 

    } 
else { 
    if(nn=="A" && n.href) 
     ...; 
    else if(nn=="IMG" & n.src) { 
     .... 
     } 
    else if(nn=="DIV") { 
     if(n.className=="indent") 
      ... 
     } 
    else if(nn=="FONT") { 
     }  
    else if(nn=="BR") { 
     } 

    if(!UNSUPPORTED_ELEMENTS[nn]) { 
     if(n.childNodes.length > 0) 
      for(var i=0; i<n.childNodes.length; i++) 
       cleanDom(result, n.childNodes[i]); 
     } 
    } 
} 
3

sto usando questo:

$(body_doc).find('body').bind('paste',function(e){ 
       var rte = $(this); 
       _activeRTEData = $(rte).html(); 
       beginLen = $.trim($(rte).html()).length; 

       setTimeout(function(){ 
        var text = $(rte).html(); 
        var newLen = $.trim(text).length; 

        //identify the first char that changed to determine caret location 
        caret = 0; 

        for(i=0;i < newLen; i++){ 
         if(_activeRTEData[i] != text[i]){ 
          caret = i-1; 
          break; 
         } 
        } 

        var origText = text.slice(0,caret); 
        var newText = text.slice(caret, newLen - beginLen + caret + 4); 
        var tailText = text.slice(newLen - beginLen + caret + 4, newLen); 

        var newText = newText.replace(/(.*(?:endif-->))|([ ]?<[^>]*>[ ]?)|(&nbsp;)|([^}]*})/g,''); 

        newText = newText.replace(/[·]/g,''); 

        $(rte).html(origText + newText + tailText); 
        $(rte).contents().last().focus(); 
       },100); 
      }); 

body_doc è l'iframe modificabile, se si utilizza un div modificabile si poteva abbandonare la .find ('body') parte. Fondamentalmente rileva un evento incolla, verifica che la posizione pulisca il nuovo testo e quindi riporti il ​​testo pulito nel punto in cui è stato incollato. (Sembra confuso ... ma non è poi così male come sembra.

Il setTimeout è necessario perché non puoi afferrare il testo finché non viene effettivamente incollato nell'elemento, incolla gli eventi non appena inizia la pasta .

0

Questo funziona alla grande per rimuovere eventuali commenti dal testo HTML, inclusi quelli da Word:

function CleanWordPastedHTML(sTextHTML) { 
    var sStartComment = "<!--", sEndComment = "-->"; 
    while (true) { 
    var iStart = sTextHTML.indexOf(sStartComment); 
    if (iStart == -1) break; 
    var iEnd = sTextHTML.indexOf(sEndComment, iStart); 
    if (iEnd == -1) break; 
    sTextHTML = sTextHTML.substring(0, iStart) + sTextHTML.substring(iEnd + sEndComment.length); 
    } 
    return sTextHTML; 
} 
0

avuto un problema simile con line-breaks essere contati come caratteri e ho dovuto rimuoverli.

$(document).ready(function(){ 
 

 
    $(".section-overview textarea").bind({ 
 
    paste : function(){ 
 
    setTimeout(function(){ 
 
     //textarea 
 
     var text = $(".section-overview textarea").val(); 
 
     // look for any "\n" occurences and replace them 
 
     var newString = text.replace(/\n/g, ''); 
 
     // print new string 
 
     $(".section-overview textarea").val(newString); 
 
    },100); 
 
    } 
 
    }); 
 
    
 
});

Problemi correlati