2010-12-21 7 views
7

Dies ist ein ziemlich diskutiertes Problem auf den jQuery-Foren, aber ich kann nicht eine Lösung für meine Situation herausfinden.jQuery Text() Funktion verliert Zeilenumbrüche in IE

Ich habe eine ungeordnete Liste mit einigen Textelementen in ihnen ... der Benutzer kann neue Listenelemente über jQuery erstellen, die in einer SQL-Datenbank gespeichert werden. Sie können auch vorhandene Listenelemente bearbeiten. Da der Text in jedem Listenelement sehr lang werden kann, haben sie auch die Möglichkeit, jedes Listenelement zu "verstecken", so dass es eine verkürzte Version der Zeichenfolge anzeigt. Dies wird durch eine benutzerdefinierte jQuery-Plugin behandelt, die Listenelemente abschneidet, die über eine bestimmte Länge sind ... hier ist das, was jeder Listeneintrag aussieht, wenn die Abschneide Plugin hat es formatiert:

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

Das Problem, das ich habe ist, dass die Der Benutzer klickt auf 'Bearbeiten' und er nimmt den Inhalt des Divs mit der Klasse 'Notiz' und weist es einem Textbereich zu. Der Benutzer kann dann den Text bearbeiten und speichern. Ich bin mit dem folgenden Skript den Inhalt des div greifen und es zu dem Text zuordnen:

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

}); 

Einmal Ich verwende eine Funktion, die ich online gefunden konvertieren die Zeilenumbrüche nach BRS gespeichert ist, bevor die Zuordnung Inhalt des Textbereich zurück in die ‚Anmerkung‘, div innerhalb der entsprechenden Listeneintrag:

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

das alles in firefox/chrom/Oper/Safari funktioniert gut ... jedoch wird IE der Linie los bricht, wenn Es greift den Text über die Funktion jQuery text(). Dies wird in den Kommentaren dieser Seite auf der jQuery-Dokumentation diskutiert:

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

Einige Leute Erfolg gehabt haben, durch das Quellelement Klonen, es in ‚pre‘ Tags Einwickeln, dann den Inhalt, dass die Einnahme und setzen es im Textbereich. Dies funktioniert für Zeilenumbrüche, bringt aber auch zusätzliche Leerzeichen, Tabs usw. mit sich und es sieht ein wenig durcheinander. Eine bessere Lösung scheint zu sein, die html() jQuery-Funktion zu verwenden, um den Text zu erfassen, dann br für Zeilenumbrüche zu ersetzen und jede andere HTML-Formatierung auszublenden.

Ich bin neu in Javascript, und ich bin Müll bei regulären Ausdrücken, so dass ich keine Ahnung haben würde, wie man das macht und mir die Zeit davon läuft! Ich brauche einen regulären Ausdruck, oder einfach nur etwas Hilfe bei der Formatierung von Zeichenfolge folgenden zu tun: OHNE

  • Entfernen Sie alle span-Tags aus einem String den Inhalt der Spanne zu entfernen (meine truncate Funktion fügt eine Spanne mit der Klasse " truncate_more“... hTML-Code, oben)

  • entfernen br die und ersetzt sie durch Zeilenumbrüche sehen, die korrekt in einem Textfeld Elemente angezeigt werden und in allen Browsern

OR .. konsistent sein, wenn jemand weiß, von eine bessere Problemumgehung zu diesem IE/textarea/linebreak Problem, ich würde wirklich einen Idioten Guide schätzen :)

Ziemlich ein bisschen Informationen für was ist wahrscheinlich eine einfache Lösung, aber ich dachte, ich würde versuchen, die Situation so gut wie ich konnte erklären ! Jede mögliche Hilfe würde sehr groß geschätzt werden ....

EDIT: ‚TheJuice Antwort unten arbeitete für die br/der IE Zeilenumbrüche Ausgabe (danke!), Aber ich brauche eine ähnliche regex durchzuführen von der loszuwerden Spannen, da sie nur einen Teil des Textes einkapseln.Ich habe versucht, die folgenden, die in Firefox, aber in IE zu funktionieren scheint, dass die Spannweiten bleiben:

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

ANOTHER EDIT: ‚TheJuice‘ löste dieses Problem zu ... meine schreckliche regex ignorieren und nur das tun, was er sagt, wenn Sie sich in der gleichen Situation befinden! Vielen Dank an alle, die Vorschläge gemacht haben ...

Antwort

6

Hier ist eine viel einfachere Lösung, um HTML in Klartext mit Zeilenumbrüchen basierend auf der Verwendung von <br> oder <p> Tags zu konvertieren.

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

Zum Beispiel ruft die folgende Methode:

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

kehrt:

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

Hoffnung, die hilft;)

+0

Super das funktioniert mit jQuery 'cheerio' für Node.js - siehe https://github.com/cheeriojs/cheerio/issues/839 – loretoparisi

6

Ich denke, so etwas wird für Sie arbeiten. http://jsfiddle.net/6qbxn/2/. Ich testete dies in IE 7 FF 4.0b7 und es funktioniert wie erwartet.

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> 

Edit: Diese richtet sich Ihr zweiter Punkt.

+0

Was Ihre erste Kugel, wenn Ihre Spannweiten nur wickeln der Text, den Sie brauchen, können Sie Ihren Selektor ändern, um sie loszuwerden. http://jsfiddle.net/6qbxn/4/ – offner

+0

Vielen Dank Jungs, das ist genau das, was ich gesucht habe! Ich wusste, es wäre etwas Einfaches. Ich habe jedoch immer noch ein kleines Problem; Die Spanne kapselt nicht den gesamten Text ein, sie beginnt auf halbem Wege. Das div wird geöffnet, dann gibt es einen Text, dann gibt es einen Bereich, der den Rest des Textes enthält, also muss ich die öffnenden und schließenden Span-Tags entfernen (blank im Kopf css wird dem öffnenden Tag über jQuery für das Abschneiden hinzugefügt Funktion - siehe Markup oben). Gibt es eine einfache Möglichkeit, dies mit einer ähnlichen Replace-Funktion zu tun? Ich bin neu in Regex, also sind meine Bemühungen ziemlich erbärmlich! –

+0

@Mr_Beagle: Ich würde den HTML-Code aus dem ersten Bereich auswählen und dann den HTML-Code aus dem zweiten Bereich hinzufügen (vorausgesetzt, Sie haben immer nur die zwei Bereiche). Danach ersetzen Sie Ihre
Sachen. Du solltest wahrscheinlich vermeiden, Regex zu verwenden, wenn du kannst, da selbst der Code, den ich dir gezeigt habe, wahrscheinlich zerbricht, wenn jemand ein Tag wie "
" macht. – offner