问题
I have a div with the attribute contentEditable set.
This allows me to have a free-form editable textarea, without the need for any form input fields: http://jsfiddle.net/M8wx9/8/
However, when I create a couple of new lines and click save button, I grab the content with the .text()
method which goes on to remove the line feeds I just entered. I need to maintain the newline characters if at all possible and store the content as plain text in the database.
I could store the HTML directly to the database by using .html()
instead of .text()
but I don't like that idea as I may need to extract this data as plain text in the future. Furthermore, pressing enter in Firefox breaks new lines with <br>
, Chrome and Safari are breaking with <div>...</div>
and Internet Explorer and Opera are using paragraphs <p>...</p>
for new lines, so it doesn't sound very easy to be able to parse the html.
How can I preserve these line feeds and store the content as plain text in the database (Similar to the way a textarea does)?
Best Regards, ns
回答1:
jQuery uses textContent
on a Node
to return the text value of an element, which will compress white space. If you want the line breaks to be maintained, you need to use innerText
which means accessing the element directly rather than through jQuery.
From your jsfiddle:
console.log($(Comments)[0].innerText);
http://jsfiddle.net/M8wx9/10/
==== update:
As a caveat to this (as Tim Down has pointed out), using innerText
will only work in webkit and microsoft browsers. If your application also supports Firefox, you will need to use regular expressions on the innerHTML in order to maintain line breaks. As an example:
$(Comments).html().trim()
.replace(/<br(\s*)\/*>/ig, '\n') // replace single line-breaks
.replace(/<[p|div]\s/ig, '\n$0') // add a line break before all div and p tags
.replace(/(<([^>]+)>)/ig, ""); // remove any remaining tags
http://jsfiddle.net/M8wx9/12/
As mentioned in the comment, the previous is not working in Chrome. Here is a working solution:
$(Comments).html().trim()
.replace(/<br\s*\/*>/ig, '\n')
.replace(/(<(p|div))/ig, '\n$1')
.replace(/(<([^>]+)>)/ig, "");
http://jsfiddle.net/M8wx9/81/
回答2:
function readContentWithBreaks(elem){
if(elem[0].innerText){
return elem[0].innerText.replace(/\n/ig,"<br>");
}else{
return elem.html();
}
}
Since webkit browsers support innerText I decided to detect for that swap the /n they add.
For Firefox it already gives the content with <br>
so we can just take it as-is.
回答3:
This sounds too simple, so I am hesitant in giving this answer, but from a quick test I ran, the following should work perfectly all right (in chrome at least):
$(".post-text").text().replace(/\n/g,"<br />")
You do have to start with a separate p or div tag though, so a text node followed by a paragraph element will not generate a line feed character.
And a jsfiddle shoing this. Still, as you already mention contentEditable isn't extremely cross browser consistent... so it might be a good idea to use an existing editor really.
来源:https://stackoverflow.com/questions/13762863/contenteditable-field-to-maintain-newlines-upon-database-entry