0

I'm create a personal CSS framework, and I've a problem with the associate JavaScript (pure JavaScript, not framework used). I've create a modal system. The system is work but, when i changed JS for used the class, I've an error: Uncaught TypeError: this.hide is not a function.

class Modal {
    constructor(modalNode) {
        this.modal = modalNode;
        this.modalsButton = document.querySelectorAll("button.modal");
        this.hide = this.hide.bind(this);

        for (let i = 0; i < this.modalsButton.length; i++) {
            let modalname = "";

            let value = searchAttributeValue(this.modalsButton[i], "data-toggle");

            if (value !== "undefined") {
                this.modalsButton[i].addEventListener("click", function(event){
                    let value = searchAttributeValue(event.target, "data-toggle");

                    if (value !== "undefined") {
                        document.querySelector(value).style.display = "block";
                    }
                });
            }
        }

        this.modal.addEventListener("click", function (event) {
            this.hide();
            /*if (event.target === this.modal) {
                event.target.style.display = "none";
            }*/
        })

        /*for (let i = 0; i < this.modals.length; i++) {
            this.modals[i].addEventListener("click", function(event){
                if (event.target === this.modals[i]) {
                    event.target.style.display = "none";
                }
            });

            let button_close = this.modals[i].querySelector("button.close[data-toggle=close]");
            button_close.addEventListener("click", function(event) {
                this.modals[i].style.display = "none";
            })
        }*/
    }

    hide() {
        this.modal.style.display = "none";
    }
}

modals = document.querySelectorAll("div.modal");
for (let i = 0; i < modals.length; i++) {
    new Modal(modals[i]);
}

But if changed hide() to this.hide = function(), the this.modal is undefined. Thanks for your help.

1 Answers1

0

When using event listeners the this pointer no longer refers to the class, but to the target element.

In general the caller of a callback function can decide what will be passed as the this pointer when invoking the function via Function.call() or Function.apply().

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

If you want to access the surrounding class, you have to save the this pointer before, e.g.

const self = this;

this.modal.addEventListener("click", function (event) {
    self.hide();
});

Alternatively, you can use an arrow function which preserves the outer scope since it cannot have own bindings, such as this.

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

this.modal.addEventListener("click", event => {
    this.hide();
});
majusebetter
  • 1,458
  • 1
  • 4
  • 13