2010-12-21 8 views
7

Este es un problema hablado de jQuery en los foros, pero no puedo encontrar una solución para mi situación.función de texto jQuery() pierde saltos de línea en el IE

que tienen una lista desordenada con algunos elementos de texto en ellos ... el usuario puede crear nuevos elementos de la lista a través de jQuery, que se guardan en una base de datos SQL. También pueden editar elementos de lista existentes. Además, como el texto de cada elemento de la lista puede ser bastante extenso, tienen la opción de "ocultar" cada elemento de la lista para que muestre una versión truncada de la cadena. Esto es manejado por un plugin de jQuery a medida que trunca los elementos de lista que se encuentran en una determinada longitud ... esto es lo que se ve cada elemento de las listas una vez que el plug-in de truncamiento se ha formateado:

<li id="item_1"> 
<div class="note"> 
    This is the text that shows when this element is truncated <span style="display: none;" class="truncate_ellipsis">...</span> 
<span style="display: inline;" class="truncate_more">This is the text that will be hidden if the user clicks on the 'hide' button</span> 
</div> 
<div class="toggle_wrapper"> 
    <div class="note_toggle"> 
     <a href="#" class="truncate_more_link">Hide note</a> 
    </div> 
    <div style="display: block;" class="note_controls"> 
     <span class="edit_note"><a href="#note_textfield" id="edit_note_1">Edit</a></span> | <span class="delete_note"><a href="#" id="delete_note_1">Delete</a></span> 
    </div> 
</div> 
</li> 

El problema que tengo es que el el usuario hace clic en 'editar' y toma los contenidos del div con la clase 'nota' y lo asigna a un área de texto. El usuario puede editar el texto y guardarlo. Estoy utilizando el siguiente script para agarrar el contenido del div y asignarlo al área de texto:

$('.edit_note a').click(function(event){ 

    // Get the parent li of the 'edit' link that was clicked 
    var parentLi = $(this).closest('li'); 

    // fade out the li that's being edited 
    parentLi.fadeOut('fast'); 

    // remove the '...' that shows when the note is truncated 
    parentLi.find('.truncate_ellipsis').remove(); 

    // find the 'note' div within the li that's being edited 
    var currentNote = parentLi.find('.note'); 

    // grab the id of this note... used when saving to the DB 
    var noteId = $(this).attr('id').substr(10); 

    // Set the current note id variable and editing status 
    currentNoteId = noteId; 
    currentNoteStatus = 'edit'; 

    //add the note ID as a hidden field to the text editor form 
    $('input[name$="note_id"]').val(noteId); 

    // grab the text from this note and add it to the text area 
    // (textarea id is 'notes_content') 
    $('#notes_content').val($.trim(currentNote.text()); // this is the text area 

    // fade in the text area so the user can edit 
    $('div.notes_textarea').fadeIn(); 

}); 

Una vez que ya se ha guardado estoy usando una función que encontré en línea para convertir los saltos de línea a RB, antes de asignar la contenido del área de texto de nuevo a la 'nota' div dentro del elemento de la lista apropiada:

function nl2br (str, is_xhtml) { 
var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';  
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2'); 
} 

todo esto funciona bien en Firefox/Chrome/Opera/Safari ... sin embargo, IE se deshace de la línea se rompe cuando agarra el texto mediante la función jQuery text(). Esto se discute en los comentarios de esta página en la documentación de jQuery:

http://api.jquery.com/text/

Algunas personas han tenido éxito mediante la clonación del elemento de origen, envolviéndolo en 'pre' etiquetas, a continuación, tomar el contenido de ese y poner en el área de texto. Esto funciona para saltos de línea, pero también trae más espacios extra, pestañas, etc. y parece un poco desordenado. Una mejor solución parece ser la de usar el html() de jQuery para agarrar el texto, vuelva a colocar de br para saltos de línea, y tira a cualquier otro formato html.

Soy nuevo en Javascript sin embargo, y estoy basura en expresiones regulares, así que no tienen ni idea de cómo hacer esto y estoy acabando el tiempo! Necesito una expresión regular, o simplemente un poco de ayuda con el formato de cadenas para hacer lo siguiente:

  • quitar todas las etiquetas span de una cadena sin necesidad de retirar el contenido del tramo (mi función truncado añade un lapso con la clase " truncate_more" ... ver código html arriba)

  • de eliminación de ancho y reemplazarlos con caracteres de nueva línea que mostrará correctamente en un elemento de área de texto y ser coherente en todos los navegadores

O .. si alguien sabe de una mejor solución a este problema de IE/textarea/linebreak, realmente apreciaría una guía de idiotas :)

Bastante información para la que probablemente sea una solución simple, pero pensé que intentaría explicar la situación lo mejor que pude ! Cualquier ayuda sería enormemente apreciada ....

EDITAR: 'La respuesta de TheJuice debajo trabajado durante los años br/línea IE rompe tema (¡gracias!), Pero necesito para llevar a cabo una expresión regular similar a deshacerse de la se extiende, ya que solo encapsulan parte del texto.He intentado lo siguiente, que parece funcionar bien en Firefox pero en IE las luces permanecen:

 var withBRs = currentNote.html(); 
    var textWithBreaks = withBRs.replace(/\<br\>/gi,'\r'); 
    textWithBreaks = textWithBreaks.replace(/\<.*span.*\>/g, ''); 

otra edición: 'TheJuice' resuelve este problema también ... Ignorar mi expresión regular horrible y simplemente hacer lo que él dice si te encuentras en la misma situación! Gracias a todos los que ofrecieron sugerencias ...

Respuesta

6

Aquí hay una solución mucho más simple para convertir cualquier HTML en texto sin formato con saltos de línea basados ​​en el uso de las etiquetas <br> o <p>.

function htmlDecodeWithLineBreaks(html) { 
    var breakToken = '_______break_______', 
     lineBreakedHtml = html.replace(/<br\s?\/?>/gi, breakToken).replace(/<p\.*?>(.*?)<\/p>/gi, breakToken + '$1' + breakToken); 
    return $('<div>').html(lineBreakedHtml).text().replace(new RegExp(breakToken, 'g'), '\n'); 
} 

Por ejemplo, llamar al siguiente método:

htmlDecodeWithLineBreaks('line 1<br>line &amp; 2<br />' + 
    'line &gt; 3<p>paragraph 1</p>line 4') 

devuelve:

line 1 
line & 2 
line > 3 
paragraph 1 
line 4 

Esperamos que ayuda;)

+0

Super esto funciona con jQuery 'cheerio' para Node.js - ver https://github.com/cheeriojs/cheerio/issues/839 – loretoparisi

6

Creo que algo como esto funcionará para usted. http://jsfiddle.net/6qbxn/2/. Probé esto en IE 7 FF 4.0b7 y funciona como se esperaba.

JS:

var withBRs = $('#brText').html(); 
var textWithBreaks = withBRs.replace(/\<br\>/gi,'\r'); 
$('#area').text(textWithBreaks); 

HTML:

<HTML> 
<body> 
    <div id="brText">Hello <br>How<br>Are<br>You?</div> 
    <textarea rows="10" id="area"> 

    </textarea> 
</body> 

Editar: Esto se refiere a su segundo punto.

+0

En cuanto a su primera bala, si sus vanos simplemente envuelven el texto que necesita puede cambiar su selector para deshacerse de ellos. http://jsfiddle.net/6qbxn/4/ – offner

+0

¡Muchas gracias chicos, eso es exactamente lo que estaba buscando! Sabía que sería algo simple. Sin embargo, todavía tengo un pequeño problema; el lapso no encapsula todo el texto, comienza a la mitad del camino. El div se abre, luego hay texto, luego hay un lapso que contiene el resto del texto, así que tengo que quitar las etiquetas de apertura y de cierre (sin tener en cuenta el css en línea se agrega a la etiqueta de apertura a través de jQuery para el truncado función - ver marcado arriba). ¿Hay una manera fácil de hacer eso con una función de reemplazo similar? ¡Soy nuevo en Regex, así que mis esfuerzos son muy patéticos! –

+0

@Mr_Beagle: seleccionaría el HTML del primer tramo y luego le agregaría el HTML del segundo tramo (suponiendo que siempre tenga solo 2 tramos). Después de eso haz tu
reemplaza cosas. Es probable que desee evitar el uso de expresiones regulares si puede, ya que incluso el código que mostré probablemente se rompa si alguien hace una etiqueta como "
". – offner

Cuestiones relacionadas