JavaScript and XHTML
Words by Daniel Aleksandersen on 2006-07-10
Using JavaScript in XHTML documents requires a bit of special attention. Here I will outline what needs be done, how, and why.
document.write()
First, and foremost: XHTML disallows document.write(). The reason for this is the fact that JavaScript is executed as the parser is (possibly) still parsing the XHTML document – and this, in turn, means that the document.write() call can make the document invalid XHTML. The XML parser demands that a document be correct. In this case, the parser cannot determine if that is the case – therefore, document.write() is outlawed. Instead, use DOM (as the FAQ says).
DOM allows you to add, alter, and remove elements to/from a structured document. This does not create the situation above, because we add elements instead of writing text, and tell the parser about it. JavaScript supports DOM, and has a big library of functions to that end. We shall look at most used ones. They are:
Element createElement(String tagname)
Text createTextNode(String data)
Node appendChild(Node newChild)
void setAttribute(String name, String value)
For more information, consult the JS DOM API.
Now, on to the code: We want this:
document.write('<p class="foo">DOM is a Good Thing!</p>');
-to work in XHTML.
This is the corresponding DOM code:
var foo = document.createElement("p");
foo.setAttribute("class", "foo");
var bar = document.createTextNode("DOM is a Good Thing!");
foo.appendChild(bar);
document.body.appendChild(foo);
We create the Element, set the attribute, create a text node. Then we append the text to the Element, and the Element to the document body.
There is no deep magic here - only a simple idea. A document consists of Nodes. Nodes come in several flavours, and can themselves contain Nodes. They can also contain primitive objects - Strings. This is the essence of the structured document idea, and you see it in normal HTML as well - substitute Nodes
for tags
.
If we have nested tags, the procedure is the same as above, but one must remember that every Node is appended only once. Thus, this:
<p><em>Foo</em></p>
Becomes:
var foo = document.createElement("p");
var bar = document.createElement("em");
var text = document.createTextNode("Foo");
//Here is the point
bar.appendChild(text);
foo.appendChild(bar);
document.body.appendChild(foo);
Had we appended the <em> Node to the document.body as well, it would appear there twice.
Other things to look for
There is another point, which is, fortunately, short. XHTML is an XML language. This, as before said, requires the parser to die on errors. Thus, you must also watch for allowed attributes in your tags, and other such things - this applies to setAttribute() as much as to normal tags. If you set an attribute which does not exist, JavaScript will gladly do it - but the parser will die on it. For instance, the script tag takes the type attribute, and not the language one, in XHTML.
Locating Elements
JS DOM also allows you to find elements in your document, and alter or remove them. For this, two functions are useful:
Element getElementById(String elementId)
NodeList getElementsByTagName(String tagname)
The first asks for the id
attribute, while the second gives you a list of all specified tags.
Removing elements is done with removeChild() and removeNode(). For more information on them, consult the API.
Third party scripts
Many Websites give out JavaScript code to use on your site - ad networks, for instance. Such code is very rarely XHTML-compatible, although I suppose that will change. For now, one can rewrite such code, replacing document.write() and any other XHTML-incompatibility. I would also encourage users to write to the providers of such scripts, especially if they do not allow you to rewrite it, and encourage them to create XHTML-compatible versions of it. The owner of this site wrote to Skype, and they promised to fix it, for instance. If they ask why?
and what's wrong with .write()?
, refer them here or to the XHTML FAQ.

Leave your comment