JavaScript pissers

Note: this was written around 2005; much has improved since, and about half of the complaints listed apply to no modern browser. I should update it, because some of this is still annoying.

why bother with JS?

The situation with JavaScript is so bad that it’s a good question why bother with it?

The allure is that it is so lightweight, and so much of it is already there. And it’s largely built in to most modern browsers. When you want to animate how the page is being displayed, or validate input in a form, or other lightweight applications, JavaScript is the ticket.

overall pissers

JavaScript was originally named LiveScript in ‘95. The name was changed when Netscape and Sun struck a deal later that year. The confusion between Java and JavaScript has caused trouble for both ever since.

There is no direct mechanism within JS to determine which version of JS is being used. You’re always forced to determine the browser version and OS, and from there to determine the JS version. (However, note that JScript does have a neat “conditional compilation” feature.) The deprecated language tag of the HTML script element is ignored by most browsers, but was never standardized.

The stupidity of the object models, both Mozilla and MS. For example setInterval, etc., crypto, etc., atob, etc., are attached to window. These functions have nothing to do with windows. Frame is a subclass of window, although it doesn’t possess many of the properties of a window.

The fact that the object models differ in so many ways.

Some versions of JS are much better at concatenating strings than others. The best seems to be NS 4.x. Generally, more recent browsers are much more fussy that everything’s the same type.

Lack of data hiding.

The properties of all the native objects should have been hidden, and accessed via functions. Terrible mistake.

Awful documentation. The only client-side docs I know are from NS, and claim to cover up though JS 1.3. “http://developer.netscape.com/docs/manuals/”. Then there’s the MS documentation for JScript.

Although the base language has now been standardized in ECMAScript, and the model for HTML documents has been standardized in the W3 DOM, the model for the browser itself is up for grabs. MS has its DHTML model. It is weak on many fronts. This means the meaning of the navigator, window, and event varies from one browser to another. Unfortunately, these are the starting points for JS programming.

specific bugs and inconsistencies

MSIE is fussy about the number of hex digits in colors—it really wants #nnnnnn precisely.

Big problems checking to see if something is undefined, or no longer used, or nullified. Have resorted to having a Boolean in parallel with the value in case of a timer.

The parseInt function fails to return a sensible number in cases when the input could easily be interpreted as a number, as in a blank string.

In some browsers, styles.left, etc., is a string, with a px suffix; in others, it’s a number.

The horror! The for...in construct doesn’t work at all in Opera or Konqueror.

Array objects are hard to identify as such. Several suggestions I’ve seen don’t work. Would have been supernice if typeof could tell this. It would be nice if you could determine the genealogy of any object. But you can’t.

If you name a function the same as a variable, MSIE 4 will report a syntax error, but not tell you what the error is.

Identifying an element of a form, sometimes have to use name instead of id.

It is handy to work with an RGB color as an integer. But I find no implementation that converts a color to an integer.

The browser program localization is the navigator object property language in all browsers except MSIE. In MS it’s browserLanguage and/or userLanguage, and there’s also systemLanguage which is presumably the system localization. Besides that, nobody uses taintEnabled, and MS crashes badly if you even attempt to determine if it exists. Then MS has a slew of extra properties nobody uses. Finally, and worse, there’s preferences in NS and userProfile in MS that allow a script to get and set incompatible user prefs using completely different methods.

Even though the user’s language preferences are broadcast to every server you touch, you have to go through the “security manager: in NS to get them, and there seems to be no way to get them in any other browser.

Each browser on each platform maps the keyboard numeric keypad differently. Why???

The specifics of event handling are different on each browser. This is due to a lack of standardization of the browser model. Events themselves are standardized in the DOM Level 2, but even MSIE 6 doesn’t support this.

work-arounds

To get HTML entities with given id, look in document.getElementByID( id ) (ECMA), then in document.all.id (MSIE), then in document.id (NS 4).

	function
	getDocumentElementByID( id )
	{
		if( document.getElementById )
			return document.getElementById( id );	// DOM
		else if( document.all )
			return document.all[id];		// MSIE
		else
			return document[id];			// old NS
	}

Likewise, for style properties of HTML entity, look in obj.style (MSIE and DOM), then in obj (NS 4).

	function
	getStyles( obj )
	{
		return obj.style ? obj.style: obj;	// MSIE and DOM : NS 4
	} 

Likewise, to find the object that originally received an event, look in the event's target property (NS and DOM) then in the event's srcElement (MSIE):

	function
	getTarget( evt )
	{
		if( evt.target )
			return evt.target;	// NS and DOM
		else
			return evt.srcElement;	// MSIE
	} 

In MSIE, the latest event is attached to window.event, and in an event handler, you must grab the event from there. In NS and the DOM Level 2, the event is passed to a handler via its argument. You can write two handlers for each event, and an isMSIE() function. A somewhat neater solution is to check the length of the arguments array:

	function
	myHandler( evt )
	{
		if( arguments.length == 0 ) // MSIE isn't DOM 2 compliant.
			evt = window.event;  // So we twirl a bit
		...
	}