Optimalworks Ltd web design, SEO, training and consultancy 

the site completely surpassed my expectations GT, AutoDirector, we build websites that work, my website is great - I love it MP, XL Autos, reach more customers, make more sales, it's more than I ever could have expected LM, Trade Cars UK, we can help your business grow, 99% of business now comes from my website GV, Bash Events, promoting standards throughout the web industry, your contribution added a level of quality we would otherwise have struggled to achieve PS, Hemsley Fraser
  1. home
  2. Services
  3. Portfolio
  4. Contact us
  5. blog

innerHTML: the ultimate alternative solution

written by Craig, 19 December 2007

innerHTML allows a JavaScript developer to insert raw HTML code into the page at a specific node, e.g. node.innerHTML = “<p>some new HTML</p>”;

It’s incredibly useful and very fast, but it comes with some baggage:

  • invalid HTML can be inserted, making errors difficult to spot and debug
  • if you want to do anything complex, innerHTML will cause problems. In particular, you may not be able to examine nodes in the resulting DOM, event handlers can be removed, some elements are not supported, and browser issues will occur.
  • it’s not a part of the W3C standard. Yet. Although most browsers support innerHTML, it just feels … a little dirty.

The alternatives until now

The main alternative is to manually update the DOM using appendChild or insertBefore. It works, but it’s no fun, requires a lot of code, and is impractical for larger chunks of HTML.

I’ve seen some great ideas that use JSON-like structures or create functions for every HTML tag. It’s clever and significantly reduces the coding effort – but they’re not as easy as innerHTML.

BetterInnerHTML: the ultimate solution!

Here’s what you’ve come for – a solution that completely replaces innerHTML, allows you to specify a code string, validates your HTML, uses safe methods to update the DOM, and does it all in less than 50 lines of JavaScript.

View the BetterInnerHTML demonstration and download page…

It works by loading the HTML string as an XML document, then recursing the nodes and copying each one into the DOM. The function takes the following arguments: BetterInnerHTML(element, HTMLstring, clearfirst);

Where:

  1. element is a DOM node
  2. HTMLstring is the HTML you want to insert, and
  3. clearfirst is an optional argument – set it to false to keep the existing child nodes and append the new HTML below them

For example: BetterInnerHTML( document.getElementById("element"), "<p>A standard <strong>HTML</strong> string.</p>" );

The advantages:

  • it’s as easy to use as innerHTML but doesn’t have the problems
  • unlike innerHTML, you do not need to destroy the existing content (set clearfirst to false).
  • invalid HTML will throw a JavaScript error or show a ‘bad XML’ message
  • it’s less than 50 lines of code – just an additional 1KB to your script library
  • it works in every mainstream browser (IE, Firefox, Opera and Safari) in HTML or XHTML pages
  • if you’re retrieving XML content via Ajax requests, there’s no need to create a new XML document – the script can be modified accordingly.

The potential pitfalls:

  • it’s slower than innerHTML for large strings or frequent inserts – but that isn’t typical in a well-devised web system
  • strictly speaking, XML manipulation methods aren’t part of the W3C standards. However, like XmlHttpRequest, they are supported by most browsers and BetterInnerHTML safely updates the DOM using the XML as a reference only.
  • it’s impossible to test all combinations of OS and browser, so let me know if you find any problems.

I still have a nagging doubt that this solution is too simple and too easy! Please leave your comments…

  • categories: all popular, free download, javascript
  • tags: ajax, dom, download, html, javascript, standards, xml
  • trackback: http://www.optimalworks.net/blog/2007/web-development/javascript/innerhtml-alternative/trackback
  • bookmark: del.icio.us, digg, facebook, twitter, reddit, Furl, Spurl, Blinklist, Slashdot, Technorati, Yahoo!

47 comments:

  1. 19 December 2007 Jonathan Snook commented

    I like that you’re using a simple solution to validate the code before insertion. One problem is that the syntax must be XHTML. As an HTML 4.01 guy myself, that’d mean I’d have to remember to close my img tags (etc) before insertion.

  2. 19 December 2007 Craig commented

    That’s true – but the method does work in HTML 4.01 pages. Keeping the code valid should also help if you’re doing further DOM manipulation.

  3. 14 January 2008 Jordi commented

    Hi, I have used your BetterInnerHTML a couple of times and I am very happy with the result. Though, when I am using JavaScript onclick or similar, the onclick is not working in IE. It does in FF. The regular InnerHTML doesn’t give me any problems. Anyone come up with a solution for this already? Regards, Jordi

  4. 15 January 2008 Craig commented

    Thanks for spotting that, Jordi. Wouldn’t life be boring without IE problems … this code would be around half its size too!

    I’ve fixed the problem so grab the new version from the download page. The solution is fairly nasty: the code checks for “on-something” attributes, then attaches the event after the node has been added to the page. The event handler is run within an eval wrapped inside another function. Yuck.

    It works, but I probably wouldn’t recommend it for complex client-side applications. It would be safer and possibly faster to attach events to nodes after they have been added to the page (with BetterInnerHTML or any other method). If you do that, then v1.0 can be used.

  5. 15 January 2008 Jordi commented

    Thank you very much for your quick reply and solution. Regards.

  6. 6 March 2008 Chris commented

    I think I found a bug. This function removes some of my tags (and their content). I’ve only tested in in IE7 so far but I stopped at that point. I’m just wondering if anyone else had had any problems or if their are any limitations.

    The tags it removed were somewhat random. Sometimes it would remove a strong tag sometimes not. I don’t really have a better example than that.

  7. 6 March 2008 Craig commented

    I have found a bug that removes content if it’s only 2 characters, but all tags should be created if you have valid XHTML.

    I’d recommend testing in Firefox because you can view the generated source using extensions like Firebug and the WDT.

    Send me your HTML string and I’ll take a look.

  8. 1 April 2008 Holger Pandel commented

    Hi! Thank you so much for this script! It absolutely made my day when trying to get a slideshow script from dynamicdrive running in combination with Joomla 1.5! Again, many thanks!

  9. 1 April 2008 Bruno Goncalves commented

    Hi.
    In our project we added the use of BetterInnerHTML to the Struts-Layout Sugest feature.

    We had to change small bits of Struts-Layout Sugest and also added BetterInnerHTML. Everything was working fine with version 1.0.

    When we upgraded to 1.1 the events stop working properly (for IE and FF).
    In our case the solution was to re-add the use of addEventToNode().

    ps.the message box didn’t allowed my portuguese name with a c,

  10. 20 May 2008 ShawnAslam commented

    hello Craig,
    First of all i what i am trying to do is to add dynamic two between two rows (5 and 6) on the change event.I was doing this through InnerHTML which working good with FF and safari but not properly aligned as i require to be in the IE 7.Then i search and found you today and then use ur solution and now facing 2 problems.1)Working very much fine in Safari but it adds after last row not between the rows how cud i do this.
    2)Its not showing any thing in IE not even single object.

  11. 27 May 2008 Craig commented

    It might be best to link to your page so we can take a look at the problem.

    You might encounter a few problems using innerHTML or BetterInnerHTML since they both add child nodes to an element. However, you’re trying to insert nodes between elements. I’d be tempted to add a TR node using insertBefore and use that as the BetterInnerHTML argument.

  12. 7 August 2008 Mike Amundsen commented

    Is there a way to capture XML parsing errors from BetterInnerHTML?

  13. 7 August 2008 Craig commented

    BetterInnerHTML just loads the string into an XML document. I don’t think you can capture XML errors – it either loads or it fails.

    Few server-side technologies have decent support for checking XML documents, so I seriously doubt it’ll ever be implemented in JavaScript.

    Can I ask why you’d need to capture errors anyway?

  14. 11 August 2008 Mike Amundsen commented

    Craig: thanks for the reply. Here’s my situation:
    I load some (X)HTML data from a database and use BetterInner… to parse that into a ‘holding’ DIV on the page. Then I use XPath to pull parts of that parsed DIV into a text window for users to edit. when they’re done, they press SUBMIT and I use BetterInner… to parse the results and place it back in the DIV. This has caused the DIV to show and XML Parser error at times. I only know this since the *saved* value shows the error text.

  15. 12 August 2008 Craig commented

    Hi Mike: I guessed it might be something to do with user input, since it would be quite easy for a user to break strict XHTML rules – especially if they cut and paste from Word or another web page.

    All I can suggest is rigorous validation of the input and removal or conversion of all ‘unusual’ characters. It might be best to use Ajax and post the data back to the server for validation and cleaning – you could then store the entered text in case any further problems arise.

    I hope that helps.

  16. 12 August 2008 Mike Amundsen commented

    Craig: thanks for the reply. i’m doing some sclient-side regex clean up along w server-side validation. i was hoping to skip validating each ‘edited region’ on the server, but suspect that will be the case. oh, well.

    still *love* the library – thanks!

  17. 4 September 2008 Malaka commented

    Hi Craig
    I am trying to use betterInnerHTML and I got ‘Object required’ at Copy(_1,_11.documentElement);
    Am I missing something?
    Would this work with Safari browser?Thanks

  18. 4 September 2008 Craig commented

    Hi. It does work in Windows Safari – I’ve not tested it on a Mac, but it should be fine.

    I’d suggest that you double-check that you’re using a correct element (i.e. not a text node) and ensure your HTML string is valid.

    Hope that helps.

  19. 4 September 2008 Malaka commented

    Thanks for ur reply…
    I am using windows Safari
    I got the error even on IE, I am trying to create an element and assgin HTML code for its innerHTML, If use the innerHTML it works fine but when I use betterinnerHTML I got the error, Any advice?

  20. 4 September 2008 Craig commented

    If innerHTML works, then there’s possibly a problem with your HTML. It must adhere to XML standards and all tags must be closed. Try using a simple string first to see if that works.

  21. 12 October 2008 Rash commented

    I didn’t go through all the comments but I feel someone should mention prototype.js’ element.update(string HTML) function. semantic and easy to use.

  22. 13 October 2008 Craig commented

    Can you provide any documentation for that method? As far as I was aware, jQuery makes use of innerHTML.

  23. 31 October 2008 Pedro commented

    I tried to put my example that is not working with a VERY simple table(just one row and one cell) and the blog blocked me

  24. 31 October 2008 Craig commented

    Hi Pedro. Rather than posting code here, please supply a URL with your code with an explanation of the problem. Thanks.

  25. 12 December 2008 Samuel commented

    Great solution. I spent the last two hours looking for something like this. “Someone somewhere must have wrote a script for this solution” I’m thinking.
    Anyway I implemented the script in my website to insert an AJAX content into a div but just can’t get in working in IE. It works in every other browser I tested it in. Any suggestions?

  26. 12 December 2008 Craig commented

    Hi Samuel. I’d suggest that you double-check the HTML for validity, but it’s likely to be fine if it’s working in other browsers. Another possibility is that IE hasn’t correctly located the DOM node where you’re inserting the HTML. Make sure that IE is reporting JS errors to help find the problem.

    Finally, if it’s practical, put the code somewhere where everyone can view it.

  27. 30 January 2009 iambrian commented

    Works great – even in ie6!

  28. 17 July 2009 Teki commented

    Great solution… but onmouseout event still doesn’t work :-(

    Is this problem ‘fixable’ or should I look for another solution?

    Thnx

  29. 17 July 2009 Craig commented

    Hi Teki,

    onmouseout should work? How are you assigning it? Within the added HTML or using JS after it’s been added? I’d recommend the latter, incidentally.

    Craig

  30. 20 July 2009 Teki commented

    I’m assigning it within added HTML (and I can’t or don’t want to assign it using JS… I’m dnamically building table body on server side and I also create all the events there). On client side I just want to assign HTML ’string’ via innerHTML to table body.. I have a simplified example of what is not working (http://www.mediafire.com/file/o1hzqz4irzz/ testEvent.html)

  31. 20 July 2009 Teki commented

    I’m assigning it within added HTML (and I can’t or don’t want to assign it using JS… I’m dnamically building table body on server side and I also create all the events there). On client side I just want to assign HTML ’string’ via innerHTML to table body.. I also have a simplified example of what is not working (but I’m not able to post url here)

  32. 20 July 2009 Craig commented

    OK – does your table event work when it’s hard-coded HTML? That’s the first test I would do.

    If it works, then you’ll really need to put a small example on a live page that we can look at.

  33. 21 July 2009 Teki commented

    My simplified example @ http:||teki.freehost386.com|testEvent.html
    (Just replace | with slash – this comment box does not allow slashes)

  34. 21 July 2009 Craig commented

    It appears that only the last defined event works.

    I’ve found the problem, fixed it, and released version 1.2. Please visit the download page.

    Multiple inline events can now be defined. However, I would still recommend adding events using JS. The code could look for HTML it recognises (say, an ID of “mytable”) and add events after the page has loaded or has been updated. It’s a far cleaner and safer method. Inline events are horrible to debug.

  35. 21 July 2009 Teki commented

    Thank you for this fix. It works. I agree..that it’s really horrible to debug inline events, but I receive table body which can contain many rows and cells with events.. and I don’t want to parse that code on client side to see if there are any events to add. I just want to put whatever I get from server side in tableBody. And for now I don’t have any problems using inline events.

  36. 21 July 2009 Craig commented

    You don’t need to attach events to every cell – attach a single event handler to the whole table. The returned event has a ‘target’ property which is the node (probably a td tag) which fired the event. It’ll certainly reduce the HTML code and make everything significantly faster.

    Hope that helps.

  37. 11 August 2009 ptsa commented

    I get this ‘XML Parsing Error: undefined entity Location’ error. And have no idea what that means.

  38. 11 August 2009 Craig commented

    An “XML Parsing Error” means there is a problem with your HTML string. It looks as though you are passing an HTML entity (such as “&quot;”) which isn’t supported.

    Replace that character. You might also be able to pass “&amp;quot;” or similar.

  39. 13 August 2009 Harro commented

    Hi Craig, thnx for the script it is working great most of the time. The only problem I have is when using a simple table. It is not showing in IE7 (haven’t tested it yet on other IE versions) but it is working on Firefox 3.5.2. Hope you can help me out.

  40. 13 August 2009 Harro commented

    Test setup: http:]]www.harroheijboer.nl]test.html (slashes aint working so I used ]

  41. 13 August 2009 Craig commented

    Mmm, that’s a little bizarre. The nodes are being added, but IE7 is choosing not to display them. IE8 works fine, though.

    I’ve tried fixing it, but there are no obvious issues. I suspect it’s something buggy in IE’s table rendering.

    It’s probably one of those things that might work sometimes and not others. Sorry I can’t help further.

  42. 13 August 2009 Harro commented

    To bad :( . Thnx for your time anyway. Need to look for an other alternative then.

  43. 13 August 2009 Harro commented

    On the forums of webdeveloper.com someone notified me about the fact that IE has another idea about valid XHTML then Firefox. Adding tbody element in the table did the trick!

  44. 14 August 2009 Craig commented

    Really? The weird thing is that it’s not invalid XHTML and it was being added to the DOM correctly. Perhaps IE6 and 7 only ‘refresh’ under certain conditions.

    Thanks for the tip, though. I’m sure it’ll come in very useful.

  45. 7 January 2010 Xunnamius commented

    Thanks for this, saved me from having to write my own!

  46. 12 January 2010 richard whitfield commented

    I am trying to insert html into a div that includes some javascript to be executed as part of the insertion. When I use the standard innerHTML it seems to ignore the javascript. What does betterinnerHTML do in this situation?

  47. 12 January 2010 Craig commented

    A JavaScript block may be inserted in both cases, but it probably wouldn’t execute. However, if the block contains a known function, you should be able to call it immediately after the insertion itself.

    That said, I wouldn’t really recommend inserting JavaScript in that way. It seems complex and could lead to security issues.

add your comments
please enter your name
please enter your email address - it will not be published anywhere
please enter your website address
please enter your comments (all are moderated and checked for spam)
  • next article: Optimalworks wins the Accessites.org award 
  • previous article: TACS 1.2 update – free PHP template system 
search
  • all popular (5)
  • courses (1)
  • general (4)
  • hardware (1)
  • software (30)
    • blogs (1)
    • free download (7)
    • web browsers (12)
    • web servers (2)
  • web development (36)
    • accessibility (4)
    • ajax (1)
    • css (2)
    • graphic design (4)
    • html (1)
    • javascript (9)
    • php (4)
    • seo (2)

tags

  • accessibility
  • ajax
  • apache
  • award
  • chrome
  • computing
  • css
  • design
  • developers
  • dom
  • download
  • editor
  • emulation
  • firefox
  • funny
  • graphics
  • hardware
  • html
  • ie
  • javascript
  • opera
  • php
  • png
  • portfolio
  • review
  • safari
  • security
  • seo
  • server
  • software
  • spam
  • ssl
  • standards
  • wordpress
  • xml
  1. site map
  2. home
  3. Services
  4. Portfolio
  5. Contact us
  6. blog
  7. RSS feed
  8. project survey

XHTML 1.0 | CSS 2.1 | WAI AAA | printer-friendly

©2010 Optimalworks Ltd, Devon, UK. Registered in England and Wales No. 5922205.

This page can be viewed at http://www.optimalworks.net/blog/2007/web-development/javascript/innerhtml-alternative