As Nik020 points out you can use a closure. An Immediately Invoked Function Expression (IIFE) creates a closure but it doesn't have to be the IIFE pattern. A normal named function will do the same thing
function main() {
var translation = 0;
function main() {
// load images
loopClosure(images);
}
function loopClosure(images) {
// setup webgl
function render() {
window.requestAnimationFrame(render);
// use translation here to update image locations
}
render();
}
document.addEventListener('keydown', keyboardHandler, false);
function keyboardHandler(event) {
if (event.key == 'ArrowLeft') {
translation--;
}
if (event.key == 'ArrowRight') {
translation++;
}
}
}
main();
The IIFE pattern just means you don't have to think up a name and the name will not conflict with other names.
You can also bind this
. Example
class App {
constructor() {
this.translation = 0;
document.addEventListener('keydown', this.keyboardHandler.bind(this), false);
}
keyboardHandler(event) {
if (event.key == 'ArrowLeft') {
this.translation--;
}
if (event.key == 'ArrowRight') {
this.translation++;
}
}
}
const app = new App();
You use arrow functions which are syntactic sugar for binding this
class App {
constructor() {
this.translation = 0;
document.addEventListener('keydown', (event) => {
if (event.key == 'ArrowLeft') {
this.translation--;
}
if (event.key == 'ArrowRight') {
this.translation++;
}
}, false);
}
}
const app = new App();
If you want to be able to remove the listener and you're using an arrow function or a bind you can store the function reference in a variable
class App {
constructor() {
this.translation = 0;
const keyboardHandler = (event) => {
if (event.key == 'ArrowLeft') {
this.translation--;
}
if (event.key == 'ArrowRight') {
this.translation++;
}
};
document.addEventListener('keydown', keyboardHandler, false);
}
}
const app = new App();
There's 4 to 10 more ways to bind this and/or make a closure.