(Feel free to reword the title; I find this hard to put into words.)
I've created a JavaScript "class" (for lack of a better word; I know JS isn't class-based) that represents a textarea
and a div
.
Every time the textarea's value is changed, I want the div's content to update accordingly, so I thought to assign an onkeyup
event handler to the textarea — however, that turned out to be more problematic than I thought.
Here's the relevant part of my HTML:
<div id="container"></div>
<script src="MyTextarea.js"></script>
<script>
var ta = new MyTextarea('container');
</script>
And here's the JS I've written so far:
function MyTextarea(id) {
this.textarea = document.createElement('textarea');
this.box = document.createElement('div');
var container = document.getElementById(id);
container.appendChild(this.textarea);
container.appendChild(this.box);
this.textarea.onkeyup = this._synchronize;
}
MyTextarea.prototype._synchronize = function () {
this.box.innerHTML = this.textarea.value;
};
Instead of working, this insists on throwing a "this.textarea" is undefined" error. It turns out that — much to my surprise — in the _synchronize
function, this
doesn't refer to the MyTextarea object, but instead to the textarea element itself. I'm puzzled as to why that would be.
What am I doing wring and/or not getting here? Is it because I'm doing this within a "class"? How can I achieve this instead?
You are losing context when you assign event handler as direct function reference. So in other words, instead of MyTextarea
instance object this
points to HTMLTextAreaElement
object.
There are multiple solutions, for example you can bind context explicitly:
this.textarea.onkeyup = this._synchronize.bind(this);
Or you could do it old-school way:
var self = this;
this.textarea.onkeyup = function() {
self._synchronize();
};