zoloft pills

innerHTML, innerText and textContent

innerHTML, innerText, textContent, html() and text()?

Assuming we have a div block that contains two lines of text and a hyperlink. We want to enable inline editing so that we only edit the text and not HTML.

div block for inline editing

And when we click the edit action, we want to be able to edit it in a textarea.

Welcome to http://www.test.com!
Hope you enjoy it!

Obviously, if we use innerHTML (or jQuery’s .html()), the textarea would show:

Welcome to <a target="_blank" href="http://www.test.com">http://www.test.com</a>!
<br><br>Hope you enjoy it!

inline editing that incorrectly shows HTML code

I do not want HTML tags! What about using 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

As mentioned before, Firefox does not support innerText, while IE does not support 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!

Linebreaks should be retained when we do inline editing. Looks like innerText is what I want! Now we have to solve the Firefox support issue.

What about jQuery’s text()?

jQuery has a nice text() method, which works in 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.

Update [11/23/2011]: jQuery has addressed this issue in version 1.7. See ticket.

My solution

Rather than messing with text(), innerText and textContent, I used the following regular expression

1
var message = div.innerHTML.replace(/\&lt;br\&gt;/gi,"\n").replace(/(&lt;([^&gt;]+)&gt;)/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.

But well, regex may not be the fastest thing. In this case, it should only be used in browsers that do not support innerText. Here is the final code:

1
2
3
4
5
if (document.body.innerText) {
   var message = div.innerText;
} else {
   var message = div.innerHTML.replace(/\&lt;br\&gt;/gi,"\n").replace(/(&lt;([^&gt;]+)&gt;)/gi, "");
}

And I know how much you love jQuery. Let’s put together a jQuery plugin!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(function($){
   $.fn.innerText = function(msg) {
         if (msg) {
            if (document.body.innerText) {
               for (var i in this) {
                  this[i].innerText = msg;
               }
            } else {
               for (var i in this) {
                  this[i].innerHTML.replace(/\&lt;br\&gt;/gi,"\n").replace(/(&lt;([^&gt;]+)&gt;)/gi, "");
               }
            }
            return this;
         } else {
            if (document.body.innerText) {
               return this[0].innerText;
            } else {
               return this[0].innerHTML.replace(/\&lt;br\&gt;/gi,"\n").replace(/(&lt;([^&gt;]+)&gt;)/gi, "");
            }
         }
   };    
})(jQuery);

Put this plugin into your JavaScript file and start using it instead of jQuery’s .text(). As demonstrated above, the benefit of using this implementation over the jQuery .text() method is that it preserves line-breaks. So, using the example in the beginning of this article, when you call div.text(), it returns…

Welcome to http://www.test.com!Hope you enjoy it!

And with our innerText() plugin, doing div.innerText() yields…

Welcome to http://www.test.com!
Hope you enjoy it!
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
10 Responses
  1. I agree. Great concept.

  2. Henry Mayors says:

    Great stuff… I’ll be sure to share this on Facebook and Twitter!

  3. Sam says:

    Very nice article mate, i’ll be using some ideas for my blog.

  4. zendrej says:

    I need the opposite of what is explained here. I have a textarea where the user types and i need to place the entered text into a div with line breaks and spaces intact in all browsers.

    can someone help !!

  5. David says:

    You can probably use the good old <pre></pre> tags, or replace new-line characters in the user input with <br>s. Something like this will do:
    t=t.replace(/\n/g,’<br>’)

  6. Mark says:

    I am looking for some help with the script that will read values from a website. Specifically, I want to read the football scores from a site (like ESPN or NFL.com) and display them in my webpage. Is this possible? Any help would be appreciated. Thanks.

  7. David says:

    Look for PHP proxy, and you will find things like http://sourceforge.net/projects/php-proxy/ . With that, you can use jQuery selectors and .html() to get what you want. If you don’t use PHP. There should be similar scripts for other environments.

  8. mahaveer sharma says:

    please write simple example of innertext and innerhtml that i can understand difference between them please…….

  9. Anonymous says:

    [...] @Kasalop.innerText hat seinen Ursprung m.W. bei Microsoft und ist nicht W3C standardkonform, siehe: Firefox has its own property called textContent, which is actually what W3C recommended. It is [...]

  10. Thanks a lot for applying some time in order to write “innerHTML, innerText and textContent | David Tong”.
    Thank you so much once more -Francisca

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>