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!

27 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!

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 (29)
    • blogs (1)
    • free download (6)
    • web browsers (12)
    • web servers (2)
  • web development (35)
    • accessibility (4)
    • ajax (1)
    • css (2)
    • graphic design (4)
    • html (1)
    • javascript (8)
    • 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

©2009 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