eventsonclickonclicklistenerevent-listener

Uncaught ReferenceError: displayText is not defined at HTMLAreaElement.<anonymous>


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.


Solution

  • 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