0

I want to change the text of an HTML div using a Javascript class object by attaching addEventListener function to an HTML button. When the button is clicked, instead of displaying "Red" in the div, the "undefined" text is shown. However, if I directly call the function changeColor using a class object, the right value is shown. I apologize for such a naïve query being newer to the field. I am following tutorials on w3schools. My code is below:

class Header {
  constructor() {
    this.mystring = "Red";
  }

  changeColor() {
    document.getElementById("div1").innerHTML = this.mystring;
  }
}

//create object of class
const myheader = new Header();

// This code does not work and shows undefined in the div   
document.getElementById("btn").addEventListener('click', myheader.changeColor);

// This code works and shows Red in the div
// myheader.changeColor();
<button id="btn">Click Me!</button>

<div id="div1"></div>
Dai
  • 141,631
  • 28
  • 261
  • 374
Osman Khalid
  • 778
  • 1
  • 7
  • 22
  • 1
    You should use `.textContent`, and not `.innerHTML` otherwise you'll introduce an XSS vulnerability to your page. – Dai Sep 11 '22 at 08:49
  • 1
    Change `document.getElementById("btn").addEventListener('click', myheader.changeColor);` to `document.getElementById("btn").addEventListener('click', myheader.changeColor.bind(myheader) );` and it will work. – Dai Sep 11 '22 at 08:51

1 Answers1

3

You sent myheader.changeColor function as a parameter without its context. Just use bind method.

class Header {
  constructor() {
    this.mystring = "Red";
  }

  changeColor() {
    document.getElementById("div1").innerHTML = this.mystring;
  }
}

//create object of class
const myheader = new Header();

// This code does not work and shows undefined in the div   
document.getElementById("btn").addEventListener('click', myheader.changeColor.bind(myheader));

// This code works and shows Red in the div
// myheader.changeColor();
<button id="btn">Click Me!</button>

<div id="div1"></div>
Dorad
  • 3,413
  • 2
  • 44
  • 71
  • Thank you, I want to add a bit more explanation for newbies like me. When I write this code: document.getElementById('btn').addEventListener('click', myheader.changeColor); Then, in the changeColor() method, the "this" object will be representing the "button" object to which the event listener is attached. And this is how the "this" object will behave in the method: changeColor() { this.style.backgroundColor="red"; // will change background color of button this.textContent = "hello"; // will change text of button } To change value of "mystring" we need "bind" call – Osman Khalid Sep 11 '22 at 11:26
  • Also, if we want to avoid use of "bind", then we can use "arrow functions". With an arrow function, "this" represents the Header object no matter who called the function – Osman Khalid Sep 11 '22 at 11:42