Is there any good reading about pitfalls of scoping when using events?
The fundamental thing to remember about a function's this keyword is
that it is set by the calling function when the function is called.
To find articles, search on "javascript this keyword" or in these
archives for "this keyword operator". Mike Winter wrote a couple of
great posts a while back.
Here are a few references - some are better than others, you should
get the idea:
Mike Winter 1 (last post):
<URL:
http://groups.google.com.au/group/c...ord+mike+winter&rnum=1&hl=en#28e16b48661bf7e2
Mike Winter 2:
<URL:
http://groups.google.com.au/group/c...ord+mike+winter&rnum=5&hl=en#62dfb987df455e19
Quirksmode:
Here is my specific issue:
function MyType()
{
this.foo = "bar";
this.textbox = document.createElement("input");
this.textbox.type = "text";
this.textbox.addEventListener("blur", this.doThings, false);
Your problem here is that when the event is called, the function's
this keyword is set to the DOM element, not to your object. You can
use call or apply to set the this keyword, or pass a reference to the
object as a parameter.
However you do it, you will probably have a closure involving a DOM
object, which will likey create a memory leak in IE. The following
article tells you how to deal with that;
someElement.appendChild(this.textbox);
}
MyType.prototype.doThings = function()
{
//Wanted "bar", but 'this' is not the MyType object.
//Rather, it's the element that triggered the event.
alert(this.foo);
}
I'm trying to have an event trigger a function call in an object
instance. Is this fundamentally impossible / undesirable in javascript?
Neither, as long as you are careful about memory usage - keep the
contstructor function small and neat and (for IE's sake) detach event
listeners onunload. Here is a very quick and dirty example, Richard
Cornford's article on closures will fill in the blanks:
<div id="div0"></div>
<script type="text/javascript">
function Foo (name, el) {
this.name = name;
this.button = document.createElement('button');
// Create a local variable for convenience
var button = this.button;
// Get a reference to the new object to use later
var obj = this;
button.onclick = function(){
// Use call to set the value of 'this'
// *when the function is called*
obj.showName.call(obj);
}
button.appendChild(
document.createTextNode('show name ' + this.name)
);
el.appendChild(button);
}
Foo.prototype.showName = function(){
alert( this.name );
}
// Create a couple of objects
var x = new Foo('Fred', document.getElementById('div0'));
var y = new Foo('Nerk', document.getElementById('div0'));
</script>