PPK on JavaScript: The DOM - Part 2/Page 2 | 2
[previous] [next]
PPK on JavaScript: The DOM - Part 3
Living with empty text nodes
Therefore, effectively empty text nodes are here to stay, and we have to learn to live with them. Their first victims are the previousSibling
and nextSibling
properties, which are rather useless since they usually refer to empty text nodes. The same happens to childNodes[]
. This nodeList, too, is riddled with empty text nodes and therefore rarely used.
Let's try to get the previousSibling
in the last code example to work. We want to insert the <p>
before the <h1>
. We already saw that this works in Explorer, but not in the other browsers:
Similarly, this works in the other browsers but not in Explorer:
The following has a better chance to work across the board:
We take the element's previousSibling
. If this turns out to be a text node, we take the previous sibling of the previousSibling
, and we continue this check until we encounter a non-text node.
There's a hidden assumption here: the parent node of the <p>
(the <body>
here, but it might be another node in other situations) never contains real text nodes that actually contain text. If you're absolutely certain that this is the case, the last example will work. But as soon as any Web developer or CMS accidentally adds a real text node as a sibling of the <p>
, the script will misfire.
By far the safest solution is not to use previousSibling
at all:
This makes sure that your script always uses the correct elements, regardless of empty text nodes.
In fact, the best defense against empty text nodes is to not use previousSibling
, nextSibling
, and childNodes[]
. In the eight example scripts, I use nextSibling
only twice (and previousSibling
and childNodes[]
not at all). In both cases I use nextSibling
when I add a new element to the document, and it doesn't really matter whether it's inserted before an empty text node or not. In cases where I have to change the order of elements that are already in the document, I always search for all relevant elements through getElementsByTagName()
.
[previous] [next]
URL: