Question

So, I using this snippet <tr onclick="this.toggleClassName('selected')"> on a web page. (a Prototype.js function) It works great. All I do is click on a table row, and it appears to get selected. It works everywhere, except IE and Opera. This is just a convenience, so I don't really care if it works, but in IE it throws an error, and asks the user if he/she would like to debug.

The error message I get is "Object doesn't support this property or method." Which object or which method might it be referring to? Any thoughts on an easy way to implement this functionality in IE? How about just not throwing error messages out to the user?

Thanks, Dave

(http://math.davehampson.net)

Was it helpful?

Solution

Yeah, this is basically the main problem with Prototype.

Prototype works differently on different browsers. On browsers that let you play with the prototypes of the host objects (like HTMLTableRowElement), it adds its own functions like toggleClassName to those prototypes, so that every time you get hold of a <tr> you can call that method on it directly. Woohoo, how convenient!

Unfortunately, being able to alter the prototypes of DOM Nodes is something that no ECMAScript or DOM standard actually endorses. It happens to work in Firefox because Mozilla are nice like that, but you can't expect it to work in all browsers; it certainly won't work in IE.

So for other browsers you have to tell Prototype to add (‘augment’) its own methods onto every single object that you want to deal with:

Element.extend(this);

Now you can call this.toggleClassName safely on all browsers.

Once you've augmented that particular <tr>, every time you access it in future, it will still be augmented, so you can still call toggleClassName on it. What's more, if you happen to access an element through Prototype methods — such as $('mytrid') — it will automatically augment it for you.

This is not a convenience feature: this is a trap. It encourages you to write code that happens to work on your browser (that supports prototype-hacking) but will fail elsewhere. It encourages you to write code that happens to work if you interact with the page elements in a certain order, that ensures they all get augmented before the augmented methods are called, but then falls over if you interact with the elements in a different order.

This is a debugging disaster, and it is Why I Do Not Use Prototype.

(Next week, for extra flamebait fun, Why I Do Not Use jQuery Either.)

OTHER TIPS

Try using this instead:

$(this).toggleClassName('selected')

Detailed reason why here: http://prototypejs.org/learn/extensions/

the 'this' keyword is a javascript fundamental and in your example would return the tr dom node. i suspect that prototypejs is attaching methods to the dom nodes, and for some reason this isn't done/working for IE and Opera.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top