innerHTML, innerText, textContent, html() and text()?
Issue: I recently ran into a bug that there is a div block (see image below) that contains a few links (as in <a> tags) and a couple of line breaks (as in <br>s). There is an edit button associated with the div block. Clicking the edit button will reveal a textarea, which should contain the plain text version of the content inside the div block.
Sample “div block” (note that the edit link is not considered part of the div):
Expected content in the textarea for the purpose of edit should be:
Welcome to http://www.test.com!
Hope you enjoy it!
However, the actual content in the textarea is:
Welcome to <a target="_blank" href="http://www.test.com">http://www.test.com</a>!<br><br>Hope you enjoy it!
The cause is that it was using the innerHTML property of the div (actually, it’s using jQuery, so it is html()), and I do not want HTML tags!
My first thought was to use innerText, which is supported by IE5.5+, Safari, Chrome and Opera. Wait… Firefox does not support innerText.
Firefox has its own property called textContent, which is actually what W3C recommended. It is also supported by Chrome and Opera. However, IE does not support it.
See the W3C DOM Compatibility table.
innerText v.s. textContent
Let’s take a look at how they behave differently in Chrome. Chrome supports both properties, but they yield different results.
Doing textContent on the aforementioned div would return:
Welcome to http://www.test.com!Hope you enjoy it!
Doing innerText on the same div would return:
Welcome to http://www.test.com!
Hope you enjoy it!
Looks like innerText is what I want!
What about jQuery’s text()?
jQuery has a nice text() method, which works on all browsers. The only issue is that it works like the textContent property in Firefox – it strips out linebreaks. We want something like innerText that honestly includes linebreaks.
My solution
Rather than messing with text(), innerText and textContent, I used the following solution
1 | var message = div.innerHTML.replace(/\<br\>/gi,"\n").replace(/(<([^>]+)>)/gi, "") |
The advantage is that innerHTML is supported in all browsers. It’s all native JavaScript, so no jQuery’s html() or text(). Replacing <br> tags by \n makes sure that it works like innerText, and the final replace() is a regular expression that removes all HTML tags.
Arguably, you could use this block instead.
1 2 3 4 5 | if (document.body.innerText) { var message = div.innerText; } else { var message = div.textContent; } |
It is a bigger block, but I believe it is faster on a big chunk of content in the div.
Comments?
Jun 04th


