In my contenteditable div, if the text is deleted (by a user), then immediately proceeded by a space (using the spacebar) and any text, empty quotes appear below the text in the DOM inspector (Chrome and Safari, tested).
Below is what's shown in the DOM inspector:
<div id="reminderTextEditable" contenteditable="true">
" test text"
""
</div>
If the text's leading space is removed in the div, the empty quotes are still there
<div id="reminderTextEditable" contenteditable="true">
"test text"
""
</div>
I tried the following code in an attempt to locate the empty quotes using Javascript, but it always alerts "1":
var list = document.getElementById('reminderTextEditable');
var list_items = list.childNodes;
alert(list_items.length);
Whatever the empty quotes are (whitespace?), they seem to be causing layout issues.
How can whatever is causing the empty quotes be removed?
If you hit enter while editing, some browsers (like Firefox) add a tag to achieve that effect. When you hit backspace, the cursor appears to erase the newline, but it does not erase the tag. It is still there. A similar issue can happen with other whitespace characters.
Mozilla has a couple pretty detailed examples which have functions that delete extra tab indentations or new lines
https://developer.mozilla.org/en-US/docs/Rich-Text_Editing_in_Mozilla.
To do it yourself you have to parse the innerHTML of the contenteditable element. If a node has no innerHTML (or is a text node with no nodeValue), delete it. Then go through the BR tags and if a tag is a BR and has no nextSibling delete it.
Perhaps your best bet would be to adjust your layout so that it doesn't get affected by this issue, either through CSS or JS if the complexity warrants it.
Related
I have an encapsulating span tag around some text which is all inside a content editable div.
Hello <font id="ud_First Name">Bryan</font>
The problem occurs when a user places the cursor directly to the right of the first letter inside this span tag and hits backspace to delete it, then types another character in its place.
Hello B<font id="ud_First Name">ryan</font>
While it properly deletes it and visually appears to add the new character in the right place, inspection of the source in chrome reveals that it is actually placing the new character OUTSIDE of the span which wreaks havoc on our user edits tracking.
I tried many different things but cannot get it to keep the cursor inside the span tag in this case under any circumstances.
Interestingly, HIGHLIGHTING the first character and then typing in place (replacement) keeps the cursor inside the span tag and it works as you'd expect.
Any ideas how to get the desired behavior (hopefully) simply?
I have the same problem (at least in chrome). interestingly enough, the same pattern inside a or a doesn't give the same problem.
my HTML is
<div ... contentEditable=true>
<h1>my title <span class="EMBEDDED">embedded content</span> end of title</h1>
</div>
the problem is that the user (in some cases) is not able to put the cursor before the e of "embedded content"
I don't have a proper fix now but in order to make sure the user at least sees the problem I used in css a
.EMBEDDED {
background-color: #ffb848;
display:none;
}
.EMBEDDED:before {
content:"{{"
}
.EMBEDDED:after {
content:"}}"
}
if I find a better solution I will come back
I know there are other questions on editable divs, but I couldn't find one specific to the Markdown-related issue I have.
User will be typing inside a ContentEditable div. And he may choose to do any number of Markdown-related things like code blocks, headers, and whatever.
I am having issues extracting the source properly and storing it into my database to be displayed again later by a standard Markdown parser. I have tried two ways:
$('.content').text()
In this method, the problem is that all the line breaks are stripped out and of course that is not okay.
$('.content').html()
In this method, I can get the line breaks working fine by using regex to replace <br\> with \n before inserting into database. But the browser also wraps things like ## Heading Here with divs, like this: <div>## Heading Here</div>. This is problematic for me because when I go to display this afterwards, I don't get the proper Markdown formatting.
What's the best (most simple and reliable) way to solve this problem as of 2015?
EDIT: Found a potential solution here: http://www.davidtong.me/innerhtml-innertext-textcontent-html-and-text/
if you check the documentation of jquery's .text() method,
The result of the .text() method is a string containing the combined text of all matched elements. (Due to variations in the HTML parsers in different browsers, the text returned may vary in newlines and other white space.)
so getting whitespaces is not guaranteed in all browsers.
try using the innerText property of the element.
document.getElementsByClassName('content')[0].innerText
this returns the text with all white spacing intact. But this is not cross browser compatible. It works in IE and Chrome, but not in Firefox.
the innerText equivalent for Firefox is textContent (link), but that strips out the whitespaces.
This is what I've been able to come up with using that link I posted above in my edit. It's in Coffeescript.
div = $('.content')[0]
if div.innerText
text = div.innerText
else
escapedText = div.innerHTML
.replace(/(?:\r\<br\>|\r|\<br\>)/g, '\n')
.replace(/(\<([^\>]+)\>)/gi, "")
text = _.unescape(escapedText)
Basically, I'm checking whether or not innerText works, and if it doesn't then we do this other thing where we:
Take the HTML, which has escaped text.
Replace all the <br> tags with line breaks.
Strip out any tags (escaped ones won't be stripped, i.e. the stuff the user types).
Unescape the escaped text.
I'm using javascript with a super simple regex to replace a "<" with the HTML character code for it so I can place some code on my site using the pre and code tags and have it done automatically.
jsFiddle link
basically I'm trying to figure out why this js code:
var str = document.getElementById("cleanme").innerHTML;
str=str.replace(/</g,"<");
document.getElementById("cleanme").innerHTML = str;
removes the "/" in the br tag
<pre><code id="cleanme">
<p><br />this is some code</p>
</code></pre>
not a huge deal because I'm just displaying code, but I'd still like to know.
it outputs this:
<p><br>this is some code</p>
thanks
I believe it has to do with the way certain browsers return the innerHTML property. If you use Google Chrome, inspect any < br/ > tag using the debugging tools and you'll notice they don't show a backslash. The same is true when Chrome returns an innerHTML property, the blackslash is stripped out.
So when you pass in:
<pre><code id="cleanme">
<p><br />this is some code</p>
</code></pre>
The browser return an innerHTML property of:
<pre><code id="cleanme">
<p><br>this is some code</p>
</code></pre>
Your RegEx is not the issue.
Your script is OK.
If you try this:
var str = '<p><br />this is some code</p>';
str=str.replace(/</g,"<");
str=str.replace(/>/g,">");
document.getElementById("cleanme").innerHTML = str;
It'll correctly print <br />.
Possibly it's effect of browser's HTML normalization.
Maybe too late to help you, and you've accepted a correct answer, but there's another big potential problem.
I tried this with Firefox 3.6.11 on Linux and 3.6.12 on Windows and they both behaved the same --
I did not see the <p><br>this is some code</p> in the Result pane on your fiddle, instead I saw simply this is some code with no markup at all.
Throwing firebug at it by adding a debugger; statement as the first line in the JavaScript pane and tracing through it, I found that str was getting a value of '\n', that is, just a newline was being returned from innerHTML and nothing else.
Thinking about this, but with no way to confirm it, I suspect it's because Firefox is building the DOM tree differently than you expect, because the HTML you're using is invalid. Inline elements are not allowed to contain block elements; specifically, the <code> tag is not allowed to contain a <p> tag, and <pre> is likewise not allowed to contain a <p> tag -- again, only limited inline elements can be used inside a <pre> tag).
I think FF is implicitly closing the code block before opening the paragraph so the innerHTML of id="cleanme" is nothing but the newline. It renders with the "pre" font as you expect because you've thrown the browser into Quirks Mode.
innerHTML does not return the literal source code, but the result of the browser's interpretation of it.
Different browsers will return very different results for innerHTML, sometimes omitting some quotes and 'optional' end tags, capitalizing some tag names and attributes, and collapsing extra white-space.
And HTML does not close open tags that can't have end tags, so they are not included either.
I have an XML document with some sample content like this:
<someTag>
<![CDATA[Hello World]]>
</someTag>
I'm parsing the above XML in JavaScript. When I try access and render the Hello World text using xmldoc.getElementsByTagName("someTag")[0].childNodes[0].textContent all I get was a blank text on screen.
The code is not returning undefined or any error messages. So I guess the code is properly accessing the message. But due to CDATA, it is not rendering properly on screen.
Anyway to fix the issue and get the Hello World out of this xml file?
Note that Firefox's behaviour is absolutely correct. someTag has three children:
A Text node containing the whitespace between the <someTag> and <!CDATA. This is one newline and one space;
the CDATASection node itself;
another whitespace Text node containing the single newline character between the end of the CDATA and the close-tag.
It's best not to rely closely on what combination of text and CDATA nodes might exist in an element if all you want is the text value inside it. Just call textContent on <someTag> itself and you'll get all the combined text content: '\n Hello World\n'. (You can .trim() this is you like.)
If you're running Firefox, maybe this is the issue you're having. The behavior looks very similair... The following might do the trick:
xmldoc.getElementsByTagName("someTag")[0].childNodes[1].textContent;
problem with IE which removes new lines from $("#content").text()
HTML Code
<div id="content">
<p>hello world</p>
<p>this is a paragraph</p>
</div>
jQuery Code
alert($("#content").text());
result (IE) IE removes new line (\n) how can i fix this problem ?
hello worldthis is a paragraph
result (FF)
hello world
this is a paragraph
take a look :
http://jsfiddle.net/vB3bx/
It works fine if you use the div's innerText property. Try replacing
alert($("#content").text());
with
alert( document.getElementById( "content" ).innerText );
Internet Explorer normalizes all white-space and new-line characters into the SPACE character. As far as I know, there is nothing you can do about it.
btw, it seems that IE9 beta changed this behavior. I get new-lines in it.
I'm pretty sure Sime Vidas is correct. I've tried just about everything and whatever I try (innerText, innerHTML, jQuery methods, TextRange, cloning element and putting it inside a pre element etc etc) white space is removed. I'm guessing IE will just remove it on any type of call. It clearly is there during rendering since a white-space:pre will show it, but retrieving it through javascript will always remove the white space except for pre and textarea content.
This behavior has changed in IE9. The only solution in older versions would be to replace new line characters with tags (or anything really, semicolon etc) on the server if possible and then replace them back into \n in javascript after retrieving the text content.
Not sure you're going to find a solution using text() if you consider the following:
Due to variations in the HTML parsers
in different browsers, the text
returned may vary in newlines and
other white space.
at http://api.jquery.com/text/