I’m creating a CoffeeScript application that overlays a webcam video with a canvas element (this is just for context and doesn’t seem to relate to my problem though). To get the proper canvas size to overlay on the video, I attach an event handler function to the loadedmetadata
event like this:
WebcamWizard.prototype.initializeUserMedia = function(stream) { // ... video = document.getElementById('webcam'); video.addEventListener('loadedmetadata', function(e) { // ... v = e.srcElement; // ... }); // ... }
This works nicely. However, my preference in this case goes to defining this handler method in a different method of this particular class like so:
WebcamWizard.prototype.initializeUserMedia = function(stream) { // ... video = document.getElementById('webcam'); video.addEventListener('loadedmetadata', this.initializeCanvas); // ... } WebcamWizard.prototype.initializeCanvas = function(e) { // ... video = e.srcElement; // ... }
The reason I prefer this is because it makes the CoffeeScript look neater and allows me to access the canvas DOM object within the class I’m working in more easily. When I do the second however, the initializeCanvas
method does not seem to be called. There is no error reported on the console either. Why is that?
Curiously, calling methods this way seems to work in the exact same way in the same file.
Advertisement
Answer
The problem is probably that “initializeCanvas” will be missing a useful this
reference when it’s called after the event happens. You’re passing a reference to the function, but the this
binding is ephemeral and will not survive.
You can wrap it in another function or use .bind()
:
var wiz = this; video.addEventListener('loadedmetadata', function() { wiz.initializeCanvas });