pagina insertar externa ejemplos ejemplo div con codigo cargar javascript jquery html css contenteditable

javascript - insertar - Extraer texto de un div divisor de contenido



insertar codigo html con jquery (6)

Aquí hay una solución (usando el guión bajo y jQuery) que parece funcionar en iOS Safari (iOS 7 y 8), Safari 8, Chrome 43 y Firefox 36 en OS X, e IE6-11 en Windows:

_.reduce($editable.contents(), function(text, node) { return text + (node.nodeValue || ''/n'' + (_.isString(node.textContent) ? node.textContent : node.innerHTML)); }, '''')

vea la página de prueba aquí: http://brokendisk.com/code/contenteditable.html

aunque creo que la respuesta real es que si no está interesado en el marcado provisto por el navegador, no debería usar el atributo contenteditable - un área de texto sería la herramienta adecuada para el trabajo.

Tengo un div configurado para el contenido contentEditable y con el estilo " white-space:pre ", por lo que mantiene las cosas como saltos de línea. En Safari, FF e IE, la división se ve y funciona igual. Todo está bien. Lo que quiero hacer es extraer el texto de este div, pero de tal manera que no pierda el formato, específicamente, los saltos de línea.

Estamos usando jQuery, cuya función text() básicamente realiza un DFS pre-pedido y une todo el contenido de esa rama del DOM en un solo bulto. Esto pierde el formato.

Eché un vistazo a la función html() , pero parece que los tres navegadores hacen cosas diferentes con el HTML real que se genera detrás de la escena en mi div contentEditable . Suponiendo que escribo esto en mi div:

1 2 3

Estos son los resultados:

Safari 4:

1 <div>2</div> <div>3</div>

Firefox 3.6:

1 <br _moz_dirty=""> 2 <br _moz_dirty=""> 3 <br _moz_dirty=""> <br _moz_dirty="" type="_moz">

IE 8:

<P>1</P><P>2</P><P>3</P>

Ugh Nada muy consistente aquí. ¡Lo sorprendente es que MSIE parece la más sensata! (Etiqueta P mayúscula y todo)

El div tendrá un estilo de configuración dinámica (tipo de letra, color, tamaño y alineación) que se realiza mediante CSS, por lo que no estoy seguro de poder usar una etiqueta pre (a la que se alude en algunas páginas que encontré utilizando Google).

¿Alguien sabe de algún código JavaScript y / o el complemento de jQuery o algo que extraiga texto de una división contentEditable de forma que se conserven los saltos de línea? Preferiría no reinventar una rueda de análisis sintáctico si no tengo que hacerlo.

Actualización: getText función getText de jQuery 1.4.2 y la modifiqué para extraerla con espacios en blanco casi intactos (solo cambié una línea donde agrego una nueva línea);

function extractTextWithWhitespace( elems ) { var ret = "", elem; for ( var i = 0; elems[i]; i++ ) { elem = elems[i]; // Get the text from text nodes and CDATA nodes if ( elem.nodeType === 3 || elem.nodeType === 4 ) { ret += elem.nodeValue + "/n"; // Traverse everything else, except comment nodes } else if ( elem.nodeType !== 8 ) { ret += extractTextWithWhitespace2( elem.childNodes ); } } return ret; }

Llamo a esta función y uso su salida para asignarla a un nodo XML con jQuery, algo así como:

var extractedText = extractTextWithWhitespace($(this)); var $someXmlNode = $(''<someXmlNode/>''); $someXmlNode.text(extractedText);

El XML resultante finalmente se envía a un servidor a través de una llamada AJAX.

Esto funciona bien en Safari y Firefox.

En IE, solo el primer ''/ n'' parece retenerse de alguna manera. Mirándolo más, parece que jQuery está configurando el texto así (línea 4004 de jQuery-1.4.2.js):

return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );

Al leer en createTextNode , parece que la implementación de IE puede combinar el espacio en blanco. ¿Es esto cierto o estoy haciendo algo mal?


Desafortunadamente, todavía tiene que manejar esto para el caso individual por navegador (no condono la detección del navegador en muchos casos, uso la detección de funciones ... pero en este caso es necesario), pero afortunadamente usted puede encargarse de ellos. todo bastante conciso, como esto:

var ce = $("<pre />").html($("#edit").html()); if($.browser.webkit) ce.find("div").replaceWith(function() { return "/n" + this.innerHTML; }); if($.browser.msie) ce.find("p").replaceWith(function() { return this.innerHTML + "<br>"; }); if($.browser.mozilla || $.browser.opera ||$.browser.msie ) ce.find("br").replaceWith("/n"); var textWithWhiteSpaceIntact = ce.text();

Puedes probarlo aquí . IE en particular es una molestia debido a la forma en que lo hace &nbsp; y nuevas líneas en la conversión de texto, es por eso que recibe el tratamiento anterior para que sea consistente, por lo que necesita 2 pases para manejarse correctamente.

En el #edit anterior está el ID del componente contentEditable , así que simplemente cámbielo o haga de esto una función, por ejemplo:

function getContentEditableText(id) { var ce = $("<pre />").html($("#" + id).html()); if ($.browser.webkit) ce.find("div").replaceWith(function() { return "/n" + this.innerHTML; }); if ($.browser.msie) ce.find("p").replaceWith(function() { return this.innerHTML + "<br>"; }); if ($.browser.mozilla || $.browser.opera || $.browser.msie) ce.find("br").replaceWith("/n"); return ce.text(); }

Puedes probar eso aquí . O, ya que esto está basado en métodos jQuery de todos modos, conviértalo en un complemento, como este:

$.fn.getPreText = function () { var ce = $("<pre />").html(this.html()); if ($.browser.webkit) ce.find("div").replaceWith(function() { return "/n" + this.innerHTML; }); if ($.browser.msie) ce.find("p").replaceWith(function() { return this.innerHTML + "<br>"; }); if ($.browser.mozilla || $.browser.opera || $.browser.msie) ce.find("br").replaceWith("/n"); return ce.text(); };

Luego puedes llamarlo con $("#edit").getPreText() , puedes probar esa versión aquí .


Descubrí esto hoy en Firefox:

Paso un div contenteditable cuyo espacio en blanco está configurado para "pre" a esta función, y funciona bruscamente.

Agregué una línea para mostrar cuántos nodos hay, y un botón que coloca la salida en otro PRE, solo para demostrar que los saltos de línea están intactos.

Básicamente dice esto:

For each child node of the DIV, if it contains the ''data'' property, add the data value to the output otherwise add an LF (or a CRLF for Windows) } and return the result.

Hay un problema, aunque. Cuando pulsa Intro al final de cualquier línea del texto original, en lugar de colocar un LF, coloca un "Â". Puede pulsar Intro nuevamente y coloca un LF allí, pero no la primera vez. Y tienes que eliminar el "Â" (parece un espacio). Imagínate, supongo que es un error.

Esto no ocurre en IE8. (cambiar textoContenido a texto interior) Hay un error diferente allí, aunque. Cuando presionas Enter, divide el nodo en 2 nodos, como lo hace en Firefox, pero la propiedad "data" de cada uno de esos nodos se convierte en "indefinida".

Estoy seguro de que hay mucho más en juego aquí de lo que parece, por lo que cualquier comentario sobre el tema será esclarecedor.

<!DOCTYPE html> <html> <HEAD> <SCRIPT type="text/javascript"> function htmlToText(elem) { var outText=""; for(var x=0; x<elem.childNodes.length; x++){ if(elem.childNodes[x].data){ outText+=elem.childNodes[x].data; }else{ outText+="/n"; } } alert(elem.childNodes.length + " Nodes: /r/n/r/n" + outText); return(outText); } </SCRIPT> </HEAD> <body> <div style="white-space:pre;" contenteditable=true id=test>Text in a pre element is displayed in a fixed-width font, and it preserves both spaces and line breaks </DIV> <INPUT type=button value="submit" onclick="document.getElementById(''test2'').textContent=htmlToText(document.getElementById(''test''))"> <PRE id=test2> </PRE> </body> </html>


Me olvidé de esta pregunta hasta ahora, cuando Nico le dio una bofetada.

Resolví el problema escribiendo la función que necesitaba, creando una función desde la base de código jQuery existente y modificándola para que funcione como yo necesitaba.

He probado esta función con Safari (WebKit), IE, Firefox y Opera. No me molesté en comprobar ningún otro navegador ya que todo el contenido Editable no es estándar. También es posible que una actualización de cualquier navegador pueda romper esta función si cambian la forma en que implementan el contenido editable. Así que ten cuidado con el programador.

function extractTextWithWhitespace(elems) { var lineBreakNodeName = "BR"; // Use <br> as a default if ($.browser.webkit) { lineBreakNodeName = "DIV"; } else if ($.browser.msie) { lineBreakNodeName = "P"; } else if ($.browser.mozilla) { lineBreakNodeName = "BR"; } else if ($.browser.opera) { lineBreakNodeName = "P"; } var extractedText = extractTextWithWhitespaceWorker(elems, lineBreakNodeName); return extractedText; } // Cribbed from jQuery 1.4.2 (getText) and modified to retain whitespace function extractTextWithWhitespaceWorker(elems, lineBreakNodeName) { var ret = ""; var elem; for (var i = 0; elems[i]; i++) { elem = elems[i]; if (elem.nodeType === 3 // text node || elem.nodeType === 4) // CDATA node { ret += elem.nodeValue; } if (elem.nodeName === lineBreakNodeName) { ret += "/n"; } if (elem.nodeType !== 8) // comment node { ret += extractTextWithWhitespace(elem.childNodes, lineBreakNodeName); } } return ret; }



this.editableVal = function(cont, opts) { if (!cont) return ''''; var el = cont.firstChild; var v = ''''; var contTag = new RegExp(''^(DIV|P|LI|OL|TR|TD|BLOCKQUOTE)$''); while (el) { switch (el.nodeType) { case 3: var str = el.data.replace(/^/n|/n$/g, '' '').replace(/[/n/xa0]/g, '' '').replace(/[ ]+/g, '' ''); v += str; break; case 1: var str = this.editableVal(el); if (el.tagName && el.tagName.match(contTag) && str) { if (str.substr(-1) != ''/n'') { str += ''/n''; } var prev = el.previousSibling; while (prev && prev.nodeType == 3 && PHP.trim(prev.nodeValue) == '''') { prev = prev.previousSibling; } if (prev && !(prev.tagName && (prev.tagName.match(contTag) || prev.tagName == ''BR''))) { str = ''/n'' + str; } }else if (el.tagName == ''BR'') { str += ''/n''; } v += str; break; } el = el.nextSibling; } return v; }