I see in some posts that people frown upon using
Why is this? and what is the correct way?
document.write() will only work while the page is being originally parsed and the DOM is being created. Once the browser gets to the closing
</body> tag and the DOM is ready, you can't use
I wouldn't say using
document.write() is correct or incorrect, it just depends on your situation. In some cases you just need to have
document.write() to accomplish the task. Look at how Google analytics gets injected into most websites.
After DOM ready, you have two ways to insert dynamic HTML (assuming we are going to insert new HTML into
Using innerHTML on a node:
var node = document.getElementById('node-id'); node.innerHTML('<p>some dynamic html</p>');
Using DOM methods:
var node = document.getElementById('node-id'); var newNode = document.createElement('p'); newNode.appendChild(document.createTextNode('some dynamic html')); node.appendChild(newNode);
Using the DOM API methods might be the purist way to do stuff, but
<script> will have to be inside your
<body> tag for this to work.
document.write() doesn't work with XHTML. It's executed after the page has finished loading and does nothing more than write out a string of HTML.
Since the actual in-memory representation of HTML is the DOM, the best way to update a given page is to manipulate the DOM directly.
The way you'd go about doing this would be to programmatically create your nodes and then attach them to an existing place in the DOM. For [purposes of a contrived] example, assuming that I've got a
div element maintaining an
ID attribute of "header," then I could introduce some dynamic text by doing this:
// create my text var sHeader = document.createTextNode('Hello world!'); // create an element for the text and append it var spanHeader = document.createElement('span'); spanHeader.appendChild(sHeader); // grab a reference to the div header var divHeader = document.getElementById('header'); // append the new element to the header divHeader.appendChild(spanHeader);
Perhaps a good idea is to use jQuery in this case. It provides handy functionality and you can do things like this:
Take a look at http://docs.jquery.com/Attributes/html#val for more information.
DOM methods, as outlined by Tom.
innerHTML, as mentioned by iHunger.
DOM methods are highly preferable to strings for setting attributes and content. If you ever find yourself writing
innerHTML= '<a href="'+path+'">'+text+'</a>' you're actually creating new cross-site-scripting security holes on the client side, which is a bit sad if you've spent any time securing your server-side.
DOM methods are traditionally described as ‘slow’ compared to innerHTML. But this isn't really the whole story. What is slow is inserting a lot of child nodes:
for (var i= 0; i<1000; i++) div.parentNode.insertBefore(document.createElement('div'), div);
This translates to a load of work for the DOM finding the right place in its nodelist to insert the element, moving the other child nodes up, inserting the new node, updating the pointers, and so on.
Setting an existing attribute's value, or a text node's data, on the other hand, is very fast; you just change a string pointer and that's it. This is going to be much faster than serialising the parent with innerHTML, changing it, and parsing it back in (and won't lose your unserialisable data like event handlers, JS references and form values).
There are techniques to do DOM manipulations without so much slow childNodes walking. In particular, be aware of the possibilities of
cloneNode, and using
DocumentFragment. But sometimes innerHTML really is quicker. You can still get the best of both worlds by using innerHTML to write your basic structure with placeholders for attribute values and text content, which you then fill in afterwards using DOM. This saves you having to write your own
escapehtml() function to get around the escaping/security problems mentioned above.
You can change the
outerHTML of an element on the page instead.