logo

Building Dynamic HTML the Proper Way

How many times have you found yourself using Microsoft proprietary code in your web pages? As an example I am thinking of the use of the IE only JavaScript properties such as innerHTML and innerText. They are irresistibly simple and easy to use. I have to admit I've used them more than a few times. But always in a strictly IE-only environment. Even then I had feelings of guilt about doing so. It's all very well relying on them in this situation but bad practice like this is never good in the long-run. What we need to do is get used to using the DOM compliant methods instead. That's what I've started doing when working on client applications. An example is the code I used in the demo I published yesterday. When you use the Add Link button and select a link it is written back to the parent window's document using code that should work with all the browsers.

As you might expect the code itself is nowhere near as simple as that you might be used to. If you want to mimic the innerHTML property you need to carefully build the HTML element-by-element before carefully placing it inside the document's object model. This can require a lot of code but it's also rewarding to know you're doing it properly. Here's some example code:

//Function to insert a link in the DOM
function doAddLink ( title, unid ) {
var container = document.getElementById('related-articles');

var div = document.createElement('div');
var lnk = document.createElement('a');
var txt = document.createTextNode(title);

lnk.setAttribute('href', 'all/' + unid + '?OpenDocument');
lnk.setAttribute('target', '_blank');
lnk.appendChild(txt);
div.setAttribute('id',unid);
div.appendChild(lnk);

container.appendChild(div);
}

//Function to remove a specific link
function doRemoveLink ( unid ) {
var div = document.getElementById(unid);
div.parentNode.removeChild(div);
}

It might look complicated but the idea is simple. Create all the elements you need to build the link. Set the attributes of each, nest them according to the rules of the DOM and insert the result in to the document. To remove the link you simply get a handle on the node and remove it from its parent node.

Note: The latest versions of Mozilla-based browsers have bowed to public pressure and included support for these innerHTML type properties. Still it's a good idea to use the DOM compliant method if you want to support as many browsers as possible. You can see browser support for innerHTML et al.

Comments

    • avatar
    • zomek
    • Wed 28 Apr 2004 08:15

    I'm not sure if using exactly setAttribute() method in the example above, got any explanation, but why not use much more cleaner form:

    lnk.href = 'all/' + unid + '?OpenDocument';

    lnk.target = '_blank';

    /* ... */

    div.id = unid;

    All of these atributes are available as a properties.

    • avatar
    • vpc
    • Wed 28 Apr 2004 11:12

    Have you tried to create a SELECT input yet using this method?

    If so, could you set the text/values using setAttribute ?

  1. Dot notation does not work in all browsers if the attribute does not already exist in the element node, whereas setAttribute() will create an attribute node if one does not exist.

    For a <select> you need to create <option> nodes. These will actually contain the values/text as attributes. So you'd create a <select> node on the document, then, for each option:

    create the <option> node using createElement()

    set the value attribute using setAttribute()

    fix it to the <select> node using appendChild()

    The text would be handled using createTextNode, and that node would be glued to the <option> using appendChild() as well.

    • avatar
    • Jake
    • Wed 28 Apr 2004 14:49

    Thanks Stan. Meant to get round to answering that question but forgot all about it. Wasn't 100% sure but I was guessing what you've outlined there would be the way to go, having to create text elements for each of the options...

    • avatar
    • Sam
    • Wed 28 Apr 2004 15:27

    FYI, here's a JavaScript constructor I wrote to use insertAdjacentHTML() for Netscape browsers. (I have a constructor for innerHTML() at home, so I'll post it when I can find it.) Enjoy!

    ====================================

    if (document.childNodes&&!document.childNodes[0].insertAdjacentHTML){

    HTMLElement.prototype.insertAdjacentHTML = function (sWhere, sHTML) {

    var df;

    var r = this.ownerDocument.createRange();

    switch (String(sWhere).toLowerCase()) {

    case "beforebegin":

    r.setStartBefore(this);

    df = r.createContextualFragment(sHTML);

    this.parentNode.insertBefore(df, this);

    break;

    case "afterbegin":

    r.selectNodeContents(this);

    r.collapse(true);

    df = r.createContextualFragment(sHTML);

    this.insertBefore(df, this.firstChild);

    break;

    case "beforeend":

    r.selectNodeContents(this);

    r.collapse(false);

    df = r.createContextualFragment(sHTML);

    this.appendChild(df);

    break;

    case "afterend":

    r.setStartAfter(this);

    df = r.createContextualFragment(sHTML);

    this.parentNode.insertBefore(df, this.nextSibling);

    break;

    }

    }

    }

  2. Yes, the DOM is pretty nice to have sometimes :) I really like:

    document.getElementsByTagName("<tagname>")

    or even better:

    document.getElementById("<id>").getElementByTagName("<tagname>")

    ..to get a nice collection of wanted elements....

    However, using the DOM is often a performance killer... in general is much slower than innerHTML.

    IE, Mozilla and Safari (among others) all supports innerHTML, so if you plan to generate a lot of html fragments and know the User-Agents that will access the pages, it might we worth to test the different methods...

    • avatar
    • Andrew Tetlaw
    • Wed 28 Apr 2004 21:26

    As part of their IEEmu library WebFX have a complete implementation of all the inner/outer properties & methods here :

    {Link}

    Including:

    innerHTML

    innerText

    outerHTML

    outerText

    insertAdjacentHTML

    insertAdjacentText

    Of course that's if you want to go the MS way :)

    • avatar
    • vpc
    • Thu 29 Apr 2004 03:07

    Thanks Stan. It was the createTextNode part that I was missing !

  3. Thanks Jake... I was immensly ignorant on this point. Those resouce links are very helpful too.

    Cheers!

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Wed 28 Apr 2004

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content