2010-05-20 26 views
22

Estoy usando un 'contenteditable' <div/> y permite pegar.Limpiar el texto pegado de Microsoft Word usando JavaScript

Es increíble la cantidad de código de marcado que se pega desde una copia del portapapeles de Microsoft Word. Estoy batallando con esto, y he conseguido aproximadamente 1/2 camino allí usando la función stripTags() de Prototypes (que desafortunadamente no parece permitirme mantener algunas etiquetas).

Sin embargo, incluso después de eso, terminé con una cantidad alucinante de código de marcado innecesario.

Así que mi pregunta es, ¿hay alguna función (usando JavaScript), o el enfoque que puedo usar que limpiará la mayoría de este marcado innecesario?

+0

mejor de las suertes con esto ... el contenido generado a partir de textos (tanto en pegar y guardar como HTML deja mucho que desear) ;-) – scunliffe

+0

me preguntó más o menos la misma pregunta en ese momento en http://stackoverflow.com/questions/391291/how-do-i-remove-word-markup-crap-when-inserting-to-a-form, pero su título es mejor. Aunque, ¿por qué limitarse a javascript y no considerar hacer esto en el servidor? –

Respuesta

18

Esta es la función que terminé escribiendo que hace el trabajo bastante bien (por lo que puedo decir de todos modos).

Estoy ciertamente abierto a sugerencias de mejora si alguien tiene alguna. Gracias.

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; 
} 

la esperanza que esto sea útil para algunos de ustedes.

2

¿Qué tal tener un botón "pegar como texto plano" que muestra un <textarea>, lo que permite al usuario pegar el texto allí? de esa forma, todas las etiquetas serán despojadas por ti. Eso es lo que hago con mi CMS; Dejé de tratar de limpiar el desorden de Word.

+0

Este sería mi peor escenario, supongo (y la forma en que se ve, puede ser el único escenario, muy deprimente). – OneNerd

+0

@OneNerd: Marqué su pregunta como favorita porque si alguien más tiene una solución mejor, ¡creo que la usaré también! – Josh

+0

, se me ocurrió algo que * creo * puede ser útil; vea mi respuesta (y mejore también, por favor) si lo desea. Gracias - – OneNerd

3

Puede usar el CKEditor completo que limpia en pasta o look at the source.

+0

alguna idea donde reside exactamente la función (¿qué archivo)? – OneNerd

+2

comienza en * .. \ fckeditor \ editor \ _source \ classesclasses \ fckpastewordcommand.js * y camina hacia atrás. –

-1

¿Podría pegar en un área de texto oculta, copiar desde el mismo texto y pegar en su destino?

+0

hmm - bueno, ¿conoce una forma de enviar el contenido pegado a un área de texto por lo que es texto sin formato en lugar del código de marcado, ya que la tecla está en el DIV, puedo leer el contenido y pasarlo al área de texto , pero no sería texto claro. – OneNerd

+0

Creo que dejar las cosas como solo texto no es la mejor solución. El formato es importante. Trabajo en una aplicación que mis clientes no quieren que se eliminen los estilos de la palabra. –

-4

Odio decirlo, pero finalmente me rendí haciendo que TinyMCE manejara Word crap como yo quería. Ahora me acaban de enviar un correo electrónico cada vez que la entrada de un usuario contiene cierto HTML (busque <span lang="en-US"> por ejemplo) y lo corrijo manualmente.

+3

Yikes: no es realmente una opción para mí. – OneNerd

+0

Esta es una muy buena idea hasta que su aplicación tenga más de 0 usuarios. –

0

Hice algo así hace mucho tiempo, donde totalmente limpio las cosas en un editor de texto enriquecido y etiquetas de fuente convertidas a estilos, brs a p, etc., para mantenerlo constante entre los navegadores y evitar que ciertas cosas feas lleguen en vía pegar. Tomé mi función recursiva y arranqué la mayor parte excepto la lógica central, este podría ser un buen punto de partida ("resultado" es un objeto que acumula el resultado, que probablemente tome un segundo pase para convertirse en una cadena), si eso es lo que necesita:

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

estoy usando esto:

$(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 es el iframe editable, si está utilizando un div editable que podría caer el .find ('cuerpo') parte. Básicamente detecta un evento pegar, comprueba que la ubicación limpie el nuevo texto y luego coloca el texto limpio donde lo pegó. (Suena confuso ... pero en realidad no es tan malo como parece.

El setTimeout es necesario porque no puedes tomar el texto hasta que esté pegado en el elemento, pegar eventos se disparan tan pronto como comienza la pegada .

0

Esto funciona muy bien para eliminar cualquier comentario de texto HTML, incluyendo los de la Palabra:

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

Tenía un problema similar con saltos de línea se cuentan como caracteres y tuve que quitarlos.

$(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); 
 
    } 
 
    }); 
 
    
 
});

Cuestiones relacionadas