Section F. innerHTML


F. innerHTML

In the previous section, I used the innerHTML property for certain jobs, but it's time to discuss it more formally. Even though officially it's a Microsoft proprietary property, it is supported by all modern browsers, and is a required item in the bag of tricks any JavaScripter should carry.

InnerHTML and the Specs

innerHTML is not a part of the W3C DOM specification. For some people, that's reason enough not to use it. Personally, I disagree sharply: as we'll see in this section and the next, innerHTML is excellently suited for some tasks, and it has perfect browser compatibility.

You'll have to decide this for yourself, but I don't see any good reasons for refusing to use innerHTML. Instead, we should try to find out in which situations innerHTML will work better than pure DOM methods, and in which situations the pure methods will have the advantage.


innerHTML gives the HTML content of an element as a string, and it also allows you to write new HTML content into an element. Take this example:

<p >This is a <strong>bold</strong> bit of text.</p> var x = document.getElementById('test'); alert(x.innerHTML); 


Now the alert faithfully says 'This is a <strong>bold</strong> bit of text.'

You can also italicize the text:

x.innerHTML = 'This is an <em>emphasized</em> bit of text.'; 


Figure 8.13. Setting the innerHTML immediately changes the document tree, too.


Garbage in, garbage out

Since innerHTML is so powerful, you should take care to always pass it correct HTML. Garbage HTML can cause very weird effects. Take this example:

x.innerHTML = 'This is <em>badly <strong>nested</em> HTML.'; alert(x.innerHTML); 


Figure 8.14. Browsers disagree sharply on the interpretation of the malformed HTML.


The browsers must solve the problem of the missing </strong> tag somehow. Each finds its own solution, and likely none of these solutions are what you want. Obviously, you should avoid this by making sure you always pass correct HTML to the innerHTML property.

Speed

innerHTML is noticeably faster than pure DOM methods in the current browsers. When you append one or two children to an element, the speed difference isn't really important; the user hardly distinguishes between, say, a 7- and a 12-millisecond delay. However, once you start creating complicated structures such as tables, using innerHTML instead of createElement()/appendChild() is a noticeable improvement.

The speed difference between innerHTML and pure DOM methods goes from three times as fast (Mozilla, Opera) to thirty times as fast (Explorer).

Speed Tests

How do I know innerHTML is faster? Because I tested it. See http://www.quirksmode.org/dom/innerhtml.html for the test page.


Examples

I don't often use innerHTML in the example scripts. None of them appends large structures to the document tree, and that's where innerHTML is most useful. Nonetheless, let's review two examples where I do use innerHTML.

In Site Survey, I want to show a text that warns the user that a popup is about to appear. I wrote a standard message, but of course any site owner should be able to change that message. Therefore, I put it in a global variable at the top of my script, and later use innerHTML to add the message to the page:

[Site Survey/survey.js, lines 6 and 52]

[View full width]

var ST_pageText = 'At the moment we\'re conducting a survey about the use of our site. For this reason a <strong>popup</strong> will be opened shortly.' // during initialization text.innerHTML = ST_pageText;


If the site owner wishes to add a bit of HTML to the message, he should be free to do so, and not be bothered having to write lots of extra appendChild() lines.

I also use innerHTML in Textarea Maxlength to add the counter to the page:

[Textarea Maxlength, line 13]

counterClone.innerHTML = '<span>0</span>/'+ textareas[i].getAttribute('maxlength'); 


This is a clear example of innerHTML's simplicity and power. If I'd restricted myself to pure W3C DOM methods, I'd have to do this:

var newSpan = document.createElement('span'); newSpan.appendChild(document.createTextNode('0')); counterClone.appendChild(newSpan); counterClone.appendChild(document.createTextNode('/'+x[i].getAttribute('maxlength'))); 


Not impossible, but the first example is more concise and easier to understand.

innerHTML and pure DOM cooperation

innerHTML and pure DOM methods cooperate perfectly; any changes you make by means of the one are immediately available to the other.

Textarea Maxlength shows that any change to the innerHTML of an element is immediately available as part of the document tree:

[Textarea Maxlength, lines 13-15, condensed]

counterClone.innerHTML = '<span>0</span>/'+textareas[i].getAttribute('maxlength'); textareas[i].relatedElement = counterClone.getElementsByTagName('span')[0]; 


First, I set the counterClone's innerHTML. Two lines later, I enter counterClone by the pure DOM getElementsByTagName() method to find the <span> element. This works fine; the browsers understand that counterClone now contains a <span>, and they make it available to normal DOM methods.

The reverse also works fine. Suppose the element with ID="test" is empty:

var x = document.getElementById('test'); x.appendChild(document.createTextNode('Test text')); alert(x.innerHTML); 


Now the alert shows 'Test text'.

outerHTML, innerText, outerText

Together with innerHTML, Microsoft created three other properties: outerHTML, innerText, and outerText. outerHTML works as innerHTML, but also shows the outer tag of which it is a property. innerText and outerText show the text (non-HTML) contained in the tag (and no, I don't have the faintest idea how outerText should differ from innerText).

Take this code example:

<p >This is a <em>test</em> text.</p> var x = document.getElementById('test'); alert(x.innerHTML); alert(x.outerHTML); alert(x.innerText); alert(x.outerText); 


Figure 8.15. innerHTML, outerHTML, innerText, and outerText.


Innertext and Textcontent

Occasionally it's useful to treat innerText as a way of reading or writing texts without going to the trouble of creating text nodes. In that case, you also need the textContent property, which is the W3C DOM equivalent of innerText.

element.innerText = element.textContent = 'The new text.'; 



These three properties are rarely used in practical Web development, partly because Mozilla doesn't support them, but mostly because the information they offer isn't very useful.

innerHTML vs. DOM

So when do you use innerHTML, and when do you use the pure DOM? In the end, this depends on your personal coding style, and it's hard to give general rules. Nonetheless, there are some advantages to using innerHTML for the creation of large amounts of HTML.

The power of innerHTML lies in the ease with which you can create complicated tree structures with just one line of code. None of the example scripts contains a case in which I have to add really huge swaths of HTML to the document, so here's a contrived example of adding a slightly more complicated structure than the ones we've seen until now:

var x = document.getElementById('writeroot'); x.innerHTML = '<ul><li>First option</li><li>Second option</li></ul>'; 


Compare this to the following script that uses pure DOM methods:

var x = document.getElementById('writeroot'); var y = document.createElement('ul'); var z = document.createElement('li'); z.appendChild(document.createTextNode('First option')); y.appendChild(z); var a = document.createElement('li'); a.appendChild(document.createTextNode('Second option')); y.appendChild(a); x.appendChild(y); 


This is rather more cumbersome, especially when you want to add a static structure.

When you work with dynamic structures, however, DOM methods become more interesting. Suppose you have an array with an unknown number of message texts. All of these texts should be shown in their own <li>s.

This is the innerHTML version:

var x = document.getElementById('writeroot'); var msg = [array with messages]; var writeString = '<ul>'; for (var i=0;i<msg.length;i++) {     writeString += '<li>' + msg[i] + '</li>'; } writeString += '</ul>'; x.innerHTML = writeString; 


This is the pure DOM version:

var x = document.getElementById('writeroot'); var msg = [array with messages]; var root = document.createElement('ul'); for (var i=0;i<msg.length;i++) {     var newLI = document.createElement('li');     var newMsg = document.createTextNode(msg[i]);     newLI.appendChild(newMsg);     root.appendChild(newLI); } x.appendChild(root); 


The innerHTML version is still shorter than the pure DOM version, although the difference is not nearly as large as in the first example.

Now let's make this example a bit more complicated. There's also an array that contains the class names the <li>s should get. With innerHTML we get this:

var x = document.getElementById('writeroot'); var msg = [array with messages]; var classes = [array with class names]; var writeString = '<ul>'; for (var i=0;i<msg.length;i++) {     writeString += '<li >' + msg[i] + '</li>'; } writeString += '</ul>'; x.innerHTML = writeString; 


With pure DOM methods we get this:

var x = document.getElementById('writeroot'); var msg = [array with messages]; var classes = [array with class names]; var root = document.createElement('ul'); for (var i=0;i<msg.length;i++) {     var newLI = document.createElement('li');     newLI.className = classes[i];     var newMsg = document.createTextNode(msg[i]);     newLI.appendChild(newMsg);     root.appendChild(newLI); } x.appendChild(root); 


For me personally, this is about the breaking point at which pure DOM methods become more attractive than innerHTML. I find the following line becoming unreadable, and it's getting easier and easier to make mistakes in the quotes and brackets:

writeString += '<li >' + msg[i] + '</li>'; 


Some of you will have started using pure DOM methods much earlier, while others will feel innerHTML is still the easier option. There is no simple right or wrong here; you should try to find your personal border between these two ways of working.



ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net