Do not use the innerHTML property on HTML objects

I already said Do not use the style property on HTML objects and as I was thinking how bad the innerHTML property can be, I considered doing an article on that subject. The problem was that stones were thrown at me after the first “Do not” article. Now I fear that this one may be worst… but I’ll stand proud…

innerHTML seems easy

I like easy things : Diner Kraft and automatic cars. It’s so easy to write HTML, why should I spend time with the DOM when I can easily do it with innerHTML?

With the Dom
[source:javascript]
var aLink = document.createElement(”a”);
aLink.href=”http://www.javascriptkata.com”;
aLink.appendChild(document.createTextNode(”Javascript Kata”);
document.body.appendChild(aLink);
[/source]

VS with innerHTML

document.body.innerHTML += "<a href=\"http://www.javascriptkata.com\">Javascript Kata</a>";

Why???

innerHTML is dirty

It may look good at first sight but it’ll look real bad the next morning without make-up. Did you noticed the \”? Prepare yourself because with innerHTML you will have a truck load of these. Take a look at this.

document.body.innerHTML += "<a href=\"http://www.javascriptkata.com\" id=\"theLink\" class=\"aLink\" title=\"Javascript\">Javascript Kata</a>";

Ouch! My eyes burn.

A lot of HTML

iInnerHTML looks worst if you have a lot of And now, what if you have a lot of HTML code embedded in your javascript, it will win the war over you. I tell you.

innerHTML and ajax

I have an idea, if my ajax request returns some HTML, I could use the innerHTML property on an HTML object and assign the ajax response to it and it would be magic!

NO! In fact, you can do it but for every reasons in the world, don’t ever do that. Yeah, I know, Yahoo!TV is doing it but don’t fall in that trap.

Ajax should return data to your application. Why? Because you’ll never know what you’ll have to do with that information. For the moment, maybe you just do a simple display of the data but sooner or later, you’ll have to re-use for another section of the page. If you return HTML, you will end up parsing it to extract the data contained in it. I tell you.

By the way, forget about that old XML thingy, try JSON

It is not standard

It doesn’t really matter to me but if you’re a W3C-compliant kind of guy, that may be a good point.

Your friend is a library

You have a lot a HTML code to produce through you javascript, go and get a good library. I can’t tell you which one to use because they all have the ups and downs. Choose one and stick to it.

Comments

  1. Andreas Ecker April 17, 2007 at 10:39:12

    Hi Dan,

    I’m no particular fan of innerHTML myself. Still, I have more or less to disagree with you on all points:

    - innerHTML is dirty
    You could use single quotes terminating the literal string. Use double quotes inside the HTML string that saves you the escaping with backslashes.

    - A lot of HTML
    It may generally be a bad decision to have a lot of either HTML or DOM manipulations in your JavaScript in the first place. If you don’t use a library like jQuery, the DOM code you need is much more verbose and harder to read.

    - innerHTML and ajax
    I think a HTML string is a fair kind of data type to use. Particularly working against legacy systems that produce HTML (common MVC web architectures) allows you to make them ajaxifyable single-page applications (”HIJAX”).

    - It is not standard
    Well, if all the standards work as stable and cross-browser as this non-standard feature, we’d all be happy, right? ;-)

  2. Dragan April 17, 2007 at 11:00:44

    And innerHTML is many times faster than DOM, so when speed is a factor you must choose innerHTML. (try to insert 1000+ elements, you will see :] )

  3. Alexey April 17, 2007 at 11:58:50

    Please answer me how to insert

  4. Alexey April 17, 2007 at 12:03:46

    input type file by DOM

  5. BK April 17, 2007 at 12:04:36

    As Dragan said, innerHTML is quite faster!
    This article shows results (that you can also experience by yourself)
    http://www.quirksmode.org/dom/innerhtml.html

    You could also run a quiery on google for innerhtml vs DOM

  6. Matthew Minix April 17, 2007 at 12:40:32

    I agree with you that innerHTML should never be used to place html returned from Ajax, however, the first complaint you mentioned doesn’t have to be true.

    If you do something like this

    elephant.innerHTML = “Honk“;

    No slashes! If for some reason you wanted quotes in the HTML, just switch their spots.

    As far as it not being W3C compatible, that is a good point against it, if you’re designing anything you hope to be around a long time without being a maintenance headache you should avoid it. If you’re putting up a page to track your cd collection, I’d say innerHTML is the better solution, less work, and renders faster.

  7. Matthew Minix April 17, 2007 at 12:42:20

    heh I was stupid with my last comment and put in the actual html… so, again

    elephant.innerHTML = “>a href=’#trunk’<Honk>/a<

    sorry for the two comments

  8. Matthew Minix April 17, 2007 at 12:43:40

    I think i’m just going to go shoot myself.

    elephant.innerHTML = “<a href=’#trunk’>Honk&lt/a>”

  9. Jeff April 17, 2007 at 12:44:50

    I have minor issues with your arguments, but you way over generalized the one on “innerHTML and ajax”. I believe your point is only valid if the data being calculated and returned from the server is ONLY returned as HTML. If I have a server-side method that returns the raw data, and another server-side method that calls the first method, then formats the data for display, there is absolutely nothing wrong with someone calling that second method using AJAX and including it on the page. If I want the raw data for any other reason in the future, I can always call the first method.

  10. Charles April 17, 2007 at 13:39:21

    All of this is well and good… except for a little problem.

    var inp = document.createElement(”INPUT”);
    inp.type = “text”;
    inp.name = “whatever”;
    my_previously_inited_form_element.appendChild(inp);

    This’ll put said text box into the form in IE… except that anything entered into the form will not be submitted, because IE does not know how to attach a name to an input element after it’s been created. It can only attach the name during creation.

    This means using innerHTML is the only way to dynamically expand a form.

  11. BK April 17, 2007 at 13:43:47

    You could then use something like:

    var inp = document.createElement(”");
    my_previously_inited_form_element.appendChild(inp);

  12. Ganeshji Marwaha April 17, 2007 at 13:45:21

    #1: innerHTML seems easy
    innerHTML is easy… and it works exactly as it should. It is faster than DOM methods. it looks better and slimmer than standard dom handling.

    #2: innerHTML is dirty
    Nope, using single and double quotes judiciously will make it cleaner than u can imagine. dom code seems a lot more dirty and bloated compared to innerHTML

    #3: A lot of HTML
    Come on. After all you are trying to create HTML there. You do the same with DOM. This is just a different route to the same destination.

    #4: It is not standard
    Yes it is not. But how many standards based techniques are as cross-browser compatible as innerHTML.

    All said, it is generally useful to use innerHTML when u receive a HTML response from the server. But, if your requirement is not to return HTML, but to return some data and perform logic on that data, build html based on that logic then innerHTML should not be used to build this HTML. In this scenario it makes sense to use dom methods.

  13. BK April 17, 2007 at 13:48:00

    In fact, based on benchmarks, using string arrays then join with innerHTML is probably still more performant than DOM in most cases…

  14. Chris Lamothe April 17, 2007 at 14:01:48

    You’re entering into a world of ideals and escaping the harsh world of reality. I’ll second what others have said about performance issues when using DOM.

    Save your energy for document.write ;-)

  15. Dan (maintainer of Javascript Kata) April 17, 2007 at 14:25:25

    Wow! So much comments in so little time.

    1. innerHTML seems easy
    I know that it’s easy. But the day you have to add some stuff to the code already in it, good luck.

    2. innerHTML is dirty
    I always use quote (”) when writing a string in javascript. It’s inconsistent to change my habits because it’s easier to use single-quote (’). I won’t…

    3. A lot of HTML
    I know how it happens. You have a link to display so you use innerHTML. Next day, you have to display the link + some text. You had a DIV around it, display the link, add a SPAN and display the text. You already have a lot more HTML than you thought. The next day, you have to add an image and it never ends. Be safe, use the DOM. ;)
    4. innerHTML and ajax
    @Jeff, I would like to see a site that is implementing that kind of approach. It seems interesting but I’m not completly sold to the idea. Could you give me an URL?

    5. It’s not standard
    I have a dream… in which every browser in the world are hands in hands… seriously, it doesn’t really matter to me.

    6. *THE PERFORMANCE*
    I know. But how many of you are writing so much HTML with javascript that the performance is really a big deal? I rather code cleanly and if there’s a problem with the performance, I’ll optimize it after. Anyway, if you write so much HTML, that’s the sign that there may be a problem with your code. Delegate a little to the server-side…

    Thanks to all of you that participate to the debate. I thought that innerHTML evilness would be widely accepted as a fact but it seems not.

  16. BK April 17, 2007 at 14:43:52

    2. innerHTML is dirty
    For my part, since old time of ASP I learned to always use different quotes for my code and the HTML. In fact, as you’re saying, you always use ” for your JS… now you simply have to always use ‘ for your HTML! :P
    3. A lot of HTML
    You will have to add the same stuff using DOM won’t you?

    6. *THE PERFORMANCE*
    I built an application once for my employer that had to deal with pages with about 30-50 table rows each containing many cells. When I built it at first, I thought I would never have more than 5 or 10 records per page and everything was working fine using the DOM. Now that the record count get bigger and bigger, it’s an awesome headache to even get a ms back and one of the things I have to do is convert back to innerHTML but to be quite honest, it’s quite harder than it seems to not break a currently running app!

  17. sick_oscar April 17, 2007 at 17:38:29

    For a few code, innerHTML is sooooo easy!

  18. AGarren April 26, 2007 at 21:13:59


    var inp = document.createElement(””);

    var inp = document.createElement(””);

    I know it works for divs, I don’t see why it wouldn’t work for inputs. It’s obviously not standards compliant but since you’re targetting IE that must not be much of a concern.

  19. AGarren April 26, 2007 at 21:16:10

    bah. that was supposed to be…
    var inp = document.createElement(”<input name=’stuff’>”);

  20. Dan (maintainer of Javascript Kata) April 27, 2007 at 06:03:06

    @AGarren (in response of Charles)
    I consider evil to target one browser only (even if I’ve done it a thousand times before). You should always write code that fits most of the more popular browsers.

  21. kourge May 18, 2007 at 21:55:28

    Using the += on innerHTML properties is asking for disaster. If you must use innerHTML, accumulate the markup in a string first, then set innerHTML to that string.

  22. BK May 19, 2007 at 08:37:07

    Or if you go for a performance oriented solution, use an array and then a join

  23. Ajaxian et Javascript Kata|Triabulle May 21, 2007 at 21:32:51

    [...] qui est celle qui me vaut le plus les foudres de mes lecteurs. Deux de mes plus controversés sont Do not use the innerHTML property on HTML objects et Do not use javascript for [...]

  24. Bennett May 29, 2007 at 18:04:23

    Charles wrote: IE does not know how to attach a name to an input element after it’s been created.

    There’s an nice solution to this problem: Setting the “name” attribute in Internet Explorer. Guaranteed 100% innerHTML-free.

  25. Nadeem June 9, 2007 at 04:04:29

    I have been searching for some code of javascript. was searching and landed here, thought that code shld work fine for me but it wasnot the case.
    what i wish to do is, i want to get all images from some html code, lets say its in a textarea, want each code to be encapsulated by hyperlink tag i.e
    [a href='url'][img][/a]
    but i wish to do this in html, it may look bbcode, but i have written it like that so that browser donot manuplate it.
    is there some one to help me in this situation

  26. Dan (maintainer of Javascript Kata) June 11, 2007 at 14:08:58

    I really don’t understand. Sorry!

  27. Frank Thürigen June 23, 2007 at 12:52:45

    Dan,

    I got a whole framework (I prefer the term “toolkit” though) that is based on innerHTML, and it does it to a virtually infinite number of recursion asynchronous… I really have to say that I was hesitating in the beginning to even try this approach - but the results have made me very optimistic. And, BTW, you have mail ;-)
    Frank

  28. Travis Hawkins August 30, 2007 at 14:15:11

    Stand Proud Bro,

    I agree with this article completely. innerHTML is going to be the death of us all as it represents a dirty little break from standards that proves to the browser designers that none of us really want the standards. We, as programmers, wish that all the browsers would get behind the standards and make our life easier. Imagine all the browsers handling DOM, JS, and Styles exactly the same. I know it’s a bit of a pipe dream but if we aren’t willing to get behind the standards that are in place we have no business expecting the browser designers to get behind them.

  29. benmullin333 October 18, 2007 at 17:25:58

    Dan–

    I’m glad I found your article. innerHTML was RE-WRITTING my anchor tag. I don’t know why or WTF, but

    foo.innerHTML(”[carrot here]a href=\”javascript:callFoo(” + Bar1 + “, ” + Bar2 + “);>”)

    would come out as [carrot here]a Bar1=”" , =”" Bar2);=” href=”javascrip….

    This helped me figure out how to get it to work.

  30. Miguel Garz January 15, 2008 at 11:20:18

    Good morning.
    I liked a lot this article. AS a Java programmer and OO analyst is seems much clear the idea to use the DOM objects, that are in the end implemented by the browser.
    Of course if speed is the matter I believe that it can be used in simple cases. However the OO aproach that the DOM objects provides higher decoupling and phisical abstraction.

  31. rook2pawn July 18, 2008 at 12:08:08

    Thank you for this article. I will be sending all my ajax data in JSON from now on. I agree with you completely. Guys, the quirksmode DOM vs InnerHTML simply shows that custom non-standard methods of COURSE will be faster, but misses the point ENTIRELY of what the internet’s REST principles : Proponents of REST argue that the Web’s scalability and growth are a direct result of a few key design principles:
    [snippet]
    All resources share a uniform interface for the transfer of state between client and resource, consisting of

    A constrained set of well-defined operations

    A constrained set of content types, optionally supporting code on demand

  32. Hostile Fork August 25, 2008 at 01:47:02

    Wanted to point something out that I discovered, which is that Mozilla explicitly says you can’t use innerHTML when building tables. When I tried to use it to do so, it completely ignored various attributes, like… say… “colspan”. Was quite perplexing to me in debugging a dynamically generated table, then I found this:

    http://developer.mozilla.org/En/DOM:element.innerHTML

    “It should never be used to write parts of a table–W3C DOM methods should be used for that—-though it can be used to write an entire table or the contents of a cell.”

    Not one of mankind’s prouder moments in API design. And it certainly doesn’t inspire confidence that other uses are going to be bug free (is it really only tables that are broken?) In any case, I only changed that bit… using innerHTML in all non-table contexts and DOM for tables. We’ll see, but maybe I will end up taking your advice in the end. :(

    That aside, I think you should reconsider your stance on JavaScript’s two delimeters for strings. It’s a language feature and might as well use it…any complaints about the lack of beauty of there not being a single “canonical required form” I won’t believe because, er, you’re programming in JavaScript. It’s already la la land! Why make it uglier than it already is?

  33. kamal March 31, 2009 at 08:51:06

    can we create a java script function which is used to convert a html string into complete DOM object. for example

Post a comment

Comments are moderated and innapropriate ones won't be approved. Please respect this public space.