0

I have a piece of JavaScript code that selects a bunch of nodes with the editable class and then loops over them adding an eventListener on each of them:

  var elements = document.querySelectorAll('.editable');
  for (const element of elements) {
     element.addEventListener('mouseover',() => {
        element.innerHTML += '<i class="far fa-edit"></i>'
    })
  }

This piece of code works fine and appends <i class="far fa-edit"></i> in the element that is "mouseovered".

However if I replace the callback function of the evenlistener with:

() => { this.innerHTML += '<i class="far fa-edit"></i>' }

I find it weird as when I console.log this or element, I get a reference to the same Node! From my understanding this is a ref to the object on which the function is called. In that case element, so both using this or element should work fine...

Why is there only one of the two version of this code working?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
David Geismar
  • 3,152
  • 6
  • 41
  • 80
  • Because arrow functions *close over* `this`, they don't get it set by how they're called. If your function were a traditional function, `this` would work just fine. If you want to use an arrow function, use the event object that it receives: `({currentTarget}) => { currentTarget.innerHTML += ...; }` (but never use `+=` with `innerHTML`). – T.J. Crowder Aug 18 '20 at 16:50
  • Re "never use `+=` with `innerHTML`: When you do that, the browser has to spin through the full contents of the element and build an HTML string that it then passes to the JavaScript layer, which then appends text to it and gives it back to the browser, which then has to parse that text as HTML, tear out all the contents of the element, and replace those contents with **new** elements created from the HTML. Instead: `.insertAdjacentHTML("beforeend", "newcontent")` (or if you're adding non-HTML text, there's `insertAdjacentText`). – T.J. Crowder Aug 18 '20 at 16:52

0 Answers0