I’ll admit, I’m a bit of a JavaScript n00b when it comes to doing UI development. One of the outside consulting projects that I’m working on is asking me to push the limits of my JavaScript knowledge, and I can definitely say the past couple of days have given me a sad realization that there are some strange oddities to JavaScript development. Once you understand that Prototyping is much like Extension Methods in .Net, that part’s pretty easy. What’s not easy is trying to figure out how to do event handing with Object Oriented classes.
Here it is in a nutshell. I have a function (keystrokeListener) defined for a class (KeystrokeHandler). The idea is I want to addEventListener the keydown event for a particular object using the keystrokeListener method in my object. No matter what I was doing (whether that be declaring the method as a static method, registering the event within the class constructor, or declaring the method name on an instance of the KeystrokeHandler) yielded the following error for a call within keystrokeListener:
/** * KeystrokeHandler object definition. */functionKeystrokeHandler(){/** * Proceeds to fetch the mapped keycode, including value for any special keybindings. * * @param {Event} event The event that was triggered. */this.getRealKeycode=function(event){varrealCode=(event.keyCode?event.keyCode:event.charCode);// Check to see if the various special keys are also depressed (ALT, CTRL, SHIFT, and META)if(event.altKey){realCode+=QT.ALT;}if(event.ctrlKey){realCode+=QT.CTRL;}if(event.shiftKey){realCode+=QT.SHIFT;}if(event.metaKey){realCode+=QT.META;}returnrealCode;};/** * A generic keystroke keyNotify used for debugging purposes. * * @param {Event} nsEvent The keydown event that triggered this keyNotify to be called. */this.keyNotify=function(nsEvent){vartrueEvent=(nsEvent)?nsEvent:window.event;alert("Keystroke: "+trueEvent.keyCode);};/** * The generic keystroke listener that is called upon each keystroke. * * @param {Event} nsEvent The keypress event that triggered this method call. */this.keystrokeListener=function(nsEvent){vartrueEvent=(nsEvent)?nsEvent:window.event;this.keyNotify(nsEvent);varrealCode=this.getRealKeycode(trueEvent);};returnthis;}functionregisterTextareaEvents(){varmainArea=document.getElementById('textarea-transcription');varkeystrokeHandler=newKeystrokeHandler();//mainArea.addEventListener('keydown', function(evt) { keystrokeHandler.keystrokeListener(evt) }, true);mainArea.addEventListener('keydown',keystrokeHandler.keystrokeListener,true);}
What was happening was the event was firing and actually calling the method appropriately. However, it was not resolving properly, as within the event handler, it was unable to find the other methods associated with the object.
The solution to fix this is actually commented out at the bottom of the code sample above. What you have to do is wrap the handler registration in an anonymous function and call it explicitly if you want this to work correctly. More specifically: