March 29, 2006
C++ style class definitions in JavaScript
Its kind of a hack, but it seems to work ok in normal conditions:function EventHandlerCompat()
{
this.init = EventHandlerCompat_init;
}
function EventHandlerCompat_init(e) {
alert(this.id);
if(!e) {
var e = event;
}
var targetNode;
if(e.originalTarget) {
targetNode = e.originalTarget;
} else if(e.srcElement) {
targetNode = e.srcElement;
}
this.targetNode = targetNode;
this.handleEvent();
}
function HandleThumbnailChange()
{
extend(this, 'EventHandlerCompat');
this.handleEvent = HandleThumbnailChange_handleEvent;
}
function HandleThumbnailChange_handleEvent()
{
this.targetNode.style.backgroundColor = '#f0f';
}
function extend(original, parent)
{
eval('var parentObject = new ' + parent + '();');
for(method in parentObject) {
eval('methodType = typeof parentObject.' + method + ';');
if(methodType == 'function') {
eval('original.' + method + ' = ' + parent + '_' + method + ';');
eval('original.parent_' + method + ' = ' + parent + '_' + method + ';');
} else {
eval('original.' + method + ' = parentObject.' + method + ';' );
}
}
}
A couple of notes, all class functions must be defined as non-anonymous functions with a name of [class_name]_[method_name]. Next, to extend a class, simply call the extend function with this as the first argument and a string with the name of the class being extended as the second object.
This won't work as expected when this is reassigned to anything but the instanciated class object. (ie: event handlers have this reassigned to the DOM node that fired the event).
March 28, 2006
Determining the context an event handler was triggered from.
*UPDATE* So I'm an idiot. In the handler function, 'this' is the node the event occurred at.I've been working on moving all of my javascript out of the HTML and into the .js file. As part of this, I needed to find out how to find the context that events are called from. So far I've been able to work out the below:
function my_event_handler(e) {
if(!e) {
var e = event;
}
var targetNode;
if(e.originalTarget) {
targetNode = e.originalTarget;
} else if(e.srcElement) {
targetNode = e.srcElement;
}
}
this sets targetNode to the DOM Node that triggered the event.
Internet Explorer pollutes JavaScript's global scope!
The folks at microsoft think people are too lazy to go to the trouble of typing out document.getElementById('foo'). So to give them an alternative, every element in your HTML that has an id is given its own variable in the global scope with the name of the id.Thanks to this, it is very easy to get namespace collisions in functions. For example, say you have a div tag with id "foo". IE will put an HTMLDiv Object into the global scope named foo. Now, say you want an array named foo. You use "foo = new Array();". IE will throw an error at this point because of the type conflict.
Thankfully there is an easy way to avoid this that should probably be done anyway. Simply declare each variable with the "var" keyword, and you won't have to deal with anything in the global scope getting in the way. Again, this is probably the propper way to do things, but its damn annoying for simple scripts.