Any time I try to add a function to an onclick or event listener I get the titled error. I don't understand why it does this. Here is the code:
export class Clickables {
constructor(game) {
this.game = game;
this.doOnce = false;
this.textDisplaying = false;
this.ladder = document.getElementById("ladder");
this.steering = document.getElementById("steering");
this.propellor = document.getElementById("propellor");
this.outAtSea = document.getElementById("outAtSea");
this.atTheShip = document.getElementById("atTheShip");
this.ladderMSG = document.getElementById("ladderMSG");
this.steeringMSG = document.getElementById("steeringMSG");
this.propellorMSG = document.getElementById("propellorMSG");
this.outAtSeaMSG = document.getElementById("outAtSeaMSG");
this.atTheShipMSG = document.getElementById("atTheShipMSG");
this.eventRect = document.getElementById("eventRect");
//an array holding all the clickables
this.clickables = [this.ladder, this.steering, this.propellor,
this.outAtSea, this.atTheShip];
//an array holding all the messages
this.messages = [this.ladderMSG, this.steeringMSG, this.propellorMSG,
this.outAtSeaMSG, this.atTheShipMSG];
}
//NOTE:
//may want tp read text one char at a time for aesthetics
//may want to fade out text for aesthetics
displayText(message) {
//prevent the messages from being clicked again
this.eventRect.style.display = "none";
//display the given message
message.style.display = "flex";
if (this.textDisplaying) {
this.textDisplaying = false; //do only once
//setTimeout does a thing after set amount of time
setTimeout(() => {
//allow the text boxes to be clicked again
this.eventRect.style.display = "initial";
//remove the given message
message.style.display = "none";
}, 5000);
} //if(this.textDisplaying)
} //displayText()
update(startButtonPressed) {
if (startButtonPressed && !this.doOnce) {
this.doOnce = true;
for (let i = 0; i < this.clickables.length; i++) {
let self = this.clickables[i];
self.addEventListener('click', function (event) {
event.preventDefault();
//do awesome stuff here
if (this.id === 'ladder') {
//stuff to do if LADDER is clicked
displayText(messages[0]);
} else if (this.id === 'steering') {
//stuff to do if STEERING is clicked
displayText(messages[1]);
} else if (this.id === 'propellor') {
//stuff to do if PROPELLOR is clicked
displayText(messages[2]);
} else if (this.id === 'outAtSea') {
//stuff to do if OUTATSEA is clicked
displayText(messages[3]);
} else if (this.id === 'atTheShip') {
//stuff to do if ATTHESHIP is clicked
displayText(messages[4]);
}
}, false);
} //for()
} //if(startButtonPressed)
} //update()
draw(context) {}
} //class Clickables
I didn't try much this time because I don't know what to do; last time I spent hours trying to find a workaround; it just seems like event listeners don't like functions.
Fixed it. I guess the event listener onclick
had a limited scope so I put the displayText
function inside of update()
and changed some of the this. variables into constants also put inside the update()
. Here is the final code and it works:
export class Clickables {
constructor(game) {
this.game = game;
this.doOnce = false;
this.ladder = document.getElementById("ladder");
this.steering = document.getElementById("steering");
this.propellor = document.getElementById("propellor");
this.outAtSea = document.getElementById("outAtSea");
this.atTheShip = document.getElementById("atTheShip");
//an array holding all the clickables
this.clickables = [this.ladder, this.steering, this.propellor,
this.outAtSea, this.atTheShip];
}
update(startButtonPressed) {
let textDisplaying = false;
const eventRect = document.getElementById("eventRect");
const ladderMSG = document.getElementById("ladderMSG");
const steeringMSG = document.getElementById("steeringMSG");
const propellorMSG = document.getElementById("propellorMSG");
const outAtSeaMSG = document.getElementById("outAtSeaMSG");
const atTheShipMSG = document.getElementById("atTheShipMSG");
const messages = [ladderMSG, steeringMSG, propellorMSG, outAtSeaMSG, atTheShipMSG];
//NOTE:
//may want tp read text one char at a time for aesthetics
//may want to fade out text for aesthetics
function displayText(message) {
//prevent the messages from being clicked again
eventRect.style.display = "none";
//display the given message
message.style.display = "flex";
if (!textDisplaying) {
textDisplaying = true; //do only once
//setTimeout does a thing after set amount of time
setTimeout(() => {
//allow the text boxes to be clicked again
eventRect.style.display = "initial";
//remove the given message
message.style.display = "none";
textDisplaying = false;
}, 5000);
} //if(this.textDisplaying)
} //displayText()
if (startButtonPressed && !this.doOnce) {
this.doOnce = true;
for (let i = 0; i < this.clickables.length; i++) {
let self = this.clickables[i];
self.addEventListener('click', function (event) {
event.preventDefault();
//do awesome stuff here
if (this.id === 'ladder') {
//stuff to do if LADDER is clicked
console.log('LADDER CLICKED');
displayText(messages[0]);
} else if (this.id === 'steering') {
console.log('STEERING CLICKED');
//console.log(this.steeringMSG);
//stuff to do if STEERING is clicked
displayText(messages[1]);
} else if (this.id === 'propellor') {
console.log('PROP CLICKED');
//stuff to do if PROPELLOR is clicked
displayText(messages[2]);
} else if (this.id === 'outAtSea') {
console.log('OUTATSEA CLICKED');
//stuff to do if OUTATSEA is clicked
displayText(messages[3]);
} else if (this.id === 'atTheShip') {
console.log('ATTHYSHIP CLICKED');
//stuff to do if ATTHESHIP is clicked
displayText(messages[4]);
}
}, false);
} //for()
} //if(startButtonPressed)
} //update()
draw(context) {}
} //class Clickables