Why DOM Suck
DOM is really really weird.
whenever there's a weird tech, there's 2 possibilities. (1) you don't understand it. (2) it is badly designed.
in my experience of weird tech, Linden Scripting Lang, AutoHotkey, after years, realized the problem isn't me, it's it. Oh, count unix in.
DOM is weird in all sorts of ways, not just 1 way. Here's a incomplete list of the problems.
Nesting and Code Sequence Order Mismatch
Here is typical code of JavaScript and DOM, for creating a SVG graphics of a rectangle and text.
// create svg element const svg1 = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg1. setAttribute ("width", "100" ); svg1. setAttribute ("height", "100" ); // create a shape const cir1 = document.createElementNS("http://www.w3.org/2000/svg", "circle"); cir1.setAttribute("cx", 0 ); cir1.setAttribute("cy", 0 ); cir1.setAttribute("r", 50); // attach the shape to svg svg1 . appendChild ( cir1 ); // attach the svg to a element on page document.getElementById ('x77738'). appendChild ( svg1 );
There are 2 major problems:
- (1) your code logic must flow in reverse direction, block by block. Doesn't matter how you arrange your code, it's either a sequence of reversed sequence, or nested sequence and the outer and inner blocks have different logical order.
- (2) lots embeded
"string"
. Not sure there's a name for this problem. But basically, it's like string manipulation, where the strings are inert objects, you can't validate or interact them until runtime, and if you got a spelling error, it's runtime error.
Notice the long url string in document.createElementNS("http://www.w3.org/2000/svg", "svg")
. What were they thinking?
insert into tree
Suppose you have a tree, and you want to append a child.
So, you do this:
node.appendChild(newNode)
However, if the newNode you are appending is a element that exist in the document, that node will be removed. So, it's rather like “removeThenAppend()”.
Now, suppose you want to remove all children. Simple, you might think node.removeAllChildren()
will do. However, there is no such function. You have to do a loop to remove each child.
while (node.firstChild) {
node.removeChild(node.firstChild);
}
alternatively, you use this invented by Microsoft:
node.innerHTML = '';
Note that, although this is quite convenient, but is odd, because it is inconsistent with the manipulating tree paradigm.
And strange thing is, this version is slower than the loop to keep removing child.
Insert Before
let's say you want to insert a node. You think:
insertBefore(newNode, existingNode)
or in OOP's style of notation:
existingNode.insertBefore(newNode)
but the actual API is:
ParentOfExistingNode.insertBefore(newNode, existingNode)
Note that, you actually have to get the parent of existing node to use it.
So, the actual code is:
existingNode.parentNode.insertBefore(newNode, existingNode)
For a API that manipulate trees, you'd think there's insertAfter()
too. But not!
2018-04-10 Note, this problem has been fixed. [JS: insertAdjacentElement]
Live Object
It's strange that some DOM function returns a live object.
For example,
document.getElementsByClassName()
returns a live NodeList or HTMLCollection.
Live object means, the result is some kinda reference to the thing, not a copy.
However, not all DOM methods that retrieve elements are live. Some returns a “copy”.
Live object is strange to work with. For example, if you try to go thru the list by a loop checking for length, and add items, it'll be a infinite loop. Because, when you add item, the length also increases.
[see DOM: Live Object]