Why do DOM interfaces suck so much?
Something occurred to me today that I (as well as probably you) have known all along; DOM interfaces suck. As I was cruising the Gecko DOM Reference Guide looking for some obscure method to jog my memory on how it works, I started wandering off onto other random methods like evt.initMouseEvent() and window.find(), both of which have horribly stupid dumb idiotic interfaces. Tell me, what is great about an API that forces you to pass in five optional arguments just to get to the one you want? For example, here is the interface for window.find:
API for window.find
window.find(aString, aCaseSensitive, aBackwards, aWrapAround,
aWholeWord, aSearchInFrames, aShowDialog);
And likewise, check out this one that allows you to simulate events in the browser:
initMouseEvent interface
vent.initMouseEvent(type, canBubble, cancelable, view,
detail, screenX, screenY, clientX, clientY,
ctrlKey, altKey, shiftKey, metaKey,
button, relatedTarget);
As far as I’m concerned, since the DOM is a slave to JavaScript, it should obey its rules and live in its spirit. A good interface should follow this simple rule. “All required arguments should have their own parameter; all optional arguments should live in one single parameter, placed as the last parameter, as an object.”
What does that mean?
If method foo takes five arguments, but the last three are optional, the interface should take in three arguments like this:
pretend foo interface
foo(requiredField1, requiredField2);
// or...
foo(requiredField1, requiredField2, {
opt_field1: bar,
opt_field2: baz,
opt_field3: thunk
});
// or...
foo(requiredField1, requiredField2, {
opt_field3: thunk
});
Optional fields should all have defaults. Which brings up another thing… some existing interfaces could also use a little face-lift enhancements. For example, addEventListener to one extent follows the rules mentioned above. But when do you ‘ever’ set the third flag to ‘true’, eg:
element.addEventListener
document.getElementById('el').addEventListener(
'click',
doFoo,
false
);
I think the Mozilla team should do some testing on how often a developer actually sets that third parameter to true. I’m willing to bet it’s less than 0.001%. There’s no reason it should not be optional with a default set to false.
Last but not least…
We should all remember this from way back… I just gotta say, wtf was this all about?
wonky.window.open
winRef = window.open(strUrl, strWindowName [, strWindowFeatures]);
// for example…
winRef = window.open(
‘foo.html’,
‘uh, a name?’,
‘menubar=yes,location=yes,resizable=HELL_NO,scrollbars=yes,status=maybe,wtf=omg’
);
To me this looks like a poor mans utility function who didn’t want to waste his time using a JavaScript library. Oh no no no, you get this built right into the browser! Yeah, for free! Granted, these interfaces were written in the 90’s, so I can’t say much, I was still fiddling with <blink>. Cheers.













October 16th, 2007 at 6:46 pm
very nice. One issue I haven’t quite worked out is, what is the best way to publicize the optional arguments? One optional params object want get parses by your typical IDE. Comments can work, issues with minification and drift / maintinance. What’s your thought?
October 16th, 2007 at 7:09 pm
Hi Steve,
I’m not, exactly… sure, what your question is. Or rather, publicizing optional args? Getting parsed by an IDE… Comments working? Drift… Yeah, I’m lost.
October 16th, 2007 at 7:38 pm
While it doesn’t make the API any more convenient, the statement that “the DOM is a slave to JavaScript” is patently false. It’s right there in the definition of the DOM. “The Document Object Model is a platform- and language-neutral interface.” Browsers typically also mirror the DOM in a C interface internally, IE also exposes it in VBScript, and Gecko is opening the gates to expose it with Python.
October 16th, 2007 at 11:22 pm
I agree with you. However - is DOM really a slave to JavaScript? Isn’t DOM a standard present in many other languages such as Python ad PHP as well? Perhaps DOM-functions makes more sense in those languages?
In JavaScript I agree it makes not that much sense. One thing I think is very stupid how to remove/disconnect a node from it’s parent:
I should be able to disconnect it from it’s parent by calling a function of the element itself, like:
October 17th, 2007 at 12:41 am
lol@dustin
….yeah Im lost too mate.
October 17th, 2007 at 2:09 am
Enter libraries…
@Pelle - that’s exactly what mootools does, and probably a lot of other libraries as well
October 17th, 2007 at 4:57 am
Sorry for being vague. How do you make sure people can figure out what the optional parameters are? Most IDEs are going to show you the parameter list:
function foo( a, b, c, d)…
I start tying “foo(” and the IDE pops up “*a*, b, c, d”. They won’t be able to tell you what members you can set in an optional params argument.
So, you have function( a, b, params ), and params can optionally take c and d. How do you make that obvious to someone looking at your code? I run into this a lot with scriptaculous. Here is the code for Effect.Highlight:
So, uhm, you can override startcolor, but what else. The list of parameters is all over the place in the code - various effects and then various places in the base class..
Comments tend to become stale over time and drift from the actual implementation. Scriptaculous is a good example - the comments on the web for a lot of items are old, or they just don’t include everything. Best if the actual code is self documenting.
Crockford suggests using the || operator - I have some issues with that: http://www.bigdumbdev.com/2007/09/using-default-params-hash-avoiding.html.
October 17th, 2007 at 7:53 pm
This is a great post, and brings up a really important point. This is a really common problem in a few APIs and libraries… my biggest complaint is about Flash embed scripts, which I was inspired to write about on my blog after reading this post about the DOM interface.
The bottom line is that I don’t understand why library and API authors aren’t taking more advantage of Object literals and JSON. All functions could really be single argument, that argument being an object with named members… makes things a lot easier to read.
October 17th, 2007 at 10:42 pm
[…] Why do DOM interfaces suck so much? […]
October 18th, 2007 at 4:23 am
“[…]horribly stupid dumb idiotic interfaces.”
I myself cannot find a better description! :)
“To me this looks like a poor mans utility function who didn’t want to waste his time using a JavaScript library”… or writing it down by himself. :)
October 18th, 2007 at 8:34 am
For JavaScript, you r right, for DOM, you r wrong. DOM is not the slave of JavaScript but a platform/language neutral API. This is why it sucks, because it can’t fit the style or utilize all the feature of a special language such as JavaScript. And wtf about window.open? It’s not a part of DOM (though it will be eventually standardized in the new spec), so it’s not the fault of designer of DOM, maybe you should ask someone in Netscape or Microsoft…
Anyway if you want a easy and smart api in JavaScript, just consider prototype, jquery or some other libs.
October 20th, 2007 at 2:37 am
“As far as I’m concerned, since the DOM is a slave to JavaScript, it should obey its rules and live in its spirit.” DOM is DOM ,DOM api has no js object, so the optional object parameter is impossible, and DOM api is not part of js, and the api is usually hard to use, and the same thing with XUL, so resig are writing the FUEL
October 20th, 2007 at 1:15 pm
I’m sure you realize the performance issues of this approach?
I’ve created a simple test of both methods. Passing an object as an argument is way slower in my firefox. Try it for yourself.
October 22nd, 2007 at 12:23 pm
Mmmm…
Yes, maybe… DOM is DOM, but just like his name say DOM is only a MODEL.
I mean DOM is a way to think about a document. DOM is, definetively, a constructor.
Isn’t so?
We use DOM interfaces to manipulate documents.
Well, not all documents, but XML-based-well-formed documents.
And most of us use to manipulate the DOM of an XHTML or XML doc via Javascript.
Noone can say this is not true! :D
The best, speedy and easy way is Javascript.
Yes, maybe someone can use XPATH (we have API for different languages) but what abut “most of us”?
DOM is DOM but effectively, in the real use of it, is a “slave to Javascript”.
November 3rd, 2007 at 8:33 pm
Dustin I have to totally agree with you on this one.
December 1st, 2007 at 5:22 am
Dustin, I should agree some but this situation is caused by developers doesnt even care about JSON.
Why don’t we code parameters set as an object and run certain things around it?
To me, the main reason that jQuery became this successful was John Resig’s amazing approach to use JSON anywhere anytime.
April 2nd, 2008 at 11:41 pm
Heh, this is so true what you wrote… The bad thing about JS is that it’s hard to make some changes in the language, since they won’t influent earlier versions of browsers.
Although, this should be fixed.