Why is this keyword returning window object not the object which is clicked?

I was building an accordion, when i click on question active class should be added but console is showing error.

const accordion=document.querySelectorAll('.content')

for(let i=0; i<accordion.length; i++){
    accordion[i].addEventListener('click',()=>{
        console.log(this);
        this.classList.toggle('active');
    })
}

please help me understand why it is not working

I suggest you to do research about limitations of arrow functions.

One of them is connected to the usage of this keyword.

The below is code snippet from my own accordion, as you can see from the code comments, I had similar issue there:

// constants

const QABlock = document.getElementsByClassName('QA');
// console.log(QABlock);//3 divs in html collection

//functions

// this keyword involved >>> CAN NOT use arrow funcs here!
const showAnswer = function() {
  // console.log('before toggling', this.classList);
  this.classList.toggle('active');
  // console.log('after toggling', this.classList);
}


//event listeners

for (let i = 0; i < QABlock.length; i++) {  
  QABlock[i].addEventListener('click', showAnswer);
}
2 Likes

Hey sukhan!
Well the short answer is that the arrow functions do not have a “this”. whenever you use “this” inside of an arrow function, that will be a reference to its parent context which in this case is the window object.

You might want to use other function types like a named function declaration or anonymous function declaration if you want to do this.

function(){

}

also, judging by your code, you can also just toggle the classlist on the individual element by doing this:

accordion[i].classList.toggle('active');

Hope this helps! :smile:

3 Likes

Thanks that helped. :smile:

1 Like

Glad to see more punjabis on the site! let me know if you need help with something else :smile:

1 Like

Good luck on your project.

1 Like