2

I am trying to bind all <a> elements to have onclick function. And while variable a is a, when I try to use keyword this inside of onclick it returns me Window object. Code:

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset='utf-8'>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
</head>
<body>
<div id="stages">
    <div><p>Część I</p></div>
    <div><a data="audio/01-1-1.mp3">Rozdział  1</a><div></div><p>44:10</p></div>
    <div><a data="audio/02-1-2.mp3">Rozdział  2</a><div></div><p>20:06</p></div>
    <div><a data="audio/03-1-3.mp3">Rozdział  3</a><div></div><p>19:16</p></div>
    <div><a data="audio/04-1-4.mp3">Rozdział  4</a><div></div><p>25:29</p></div>
    <div><a data="audio/05-1-5.mp3">Rozdział  5</a><div></div><p>32:16</p></div>
    <div><a data="audio/06-1-6.mp3">Rozdział  6</a><div></div><p>13:06</p></div>
    <div><a data="audio/07-1-7.mp3">Rozdział  7</a><div></div><p>28:38</p></div>
    <div><a data="audio/08-1-8.mp3">Rozdział  8</a><div></div><p>51:59</p></div>
</div>

<script>
const a = document.querySelector('#stages a')
console.log(a)
a.onclick = () => {
    console.log(this);
}
</script>
</body>
</html>
error_man
  • 98
  • 9
  • 1
    this keyword doesn't work with arrow function – dhruv champaneri May 09 '22 at 07:41
  • 1
    Does this answer your question? [Can you bind 'this' in an arrow function?](https://stackoverflow.com/questions/33308121/can-you-bind-this-in-an-arrow-function) – Lain May 09 '22 at 07:43
  • 1
    Change `() =>` to `function ()` and it will work. Arrow functions are transparent towards the outer scope in terms of `this`, they can't have their own `this`. – CherryDT May 09 '22 at 07:54
  • 1
    Does this answer your question? [Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?](https://stackoverflow.com/questions/34361379/are-arrow-functions-and-functions-equivalent-interchangeable) – CherryDT May 09 '22 at 07:55

2 Answers2

2

In order to use this, you need to create a regular anonymous function rather than an arrow function.

const anchors = [...document.querySelectorAll("#stages a")];

anchors.forEach(a => {
   console.log(a);

   a.onclick = function () {
      console.log(this);
   };
});
Ar Rakin
  • 534
  • 3
  • 15
1

It's normal, as you're in window closure and you use an arrow function, if you need to have access to your element, you can add a prop to your arrow function like this:

const stages = [...document.querySelectorAll("#stages a")];
stages.forEach((a) => a.onclick = (e) => {
  console.log(e.currentTarget);
});
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset='utf-8'>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
</head>
<body>
<div id="stages">
    <div><p>Część I</p></div>
    <div><a data="audio/01-1-1.mp3"><strong>Rozdział  1</strong></a><div></div><p>44:10</p></div>
    <div><a data="audio/02-1-2.mp3">Rozdział  2</a><div></div><p>20:06</p></div>
    <div><a data="audio/03-1-3.mp3">Rozdział  3</a><div></div><p>19:16</p></div>
    <div><a data="audio/04-1-4.mp3">Rozdział  4</a><div></div><p>25:29</p></div>
    <div><a data="audio/05-1-5.mp3">Rozdział  5</a><div></div><p>32:16</p></div>
    <div><a data="audio/06-1-6.mp3">Rozdział  6</a><div></div><p>13:06</p></div>
    <div><a data="audio/07-1-7.mp3">Rozdział  7</a><div></div><p>28:38</p></div>
    <div><a data="audio/08-1-8.mp3">Rozdział  8</a><div></div><p>51:59</p></div>
</div>


</body>
</html>
  • These are not the same. `this` would be the `` tag that the event listener was attached to, while `event.target` would be the element that was actually clicked. (For example, if you have `Hello World!` and you click on the word `World`, then `event.target` would be the `` tag and not the ``.) – CherryDT May 09 '22 at 07:57
  • YAGNI principle, in this specific question, we don't have text wrapped around a tag, so it will work – Artash Grigoryan May 09 '22 at 08:26
  • Yes but Stack Overflow's main purpose is building a generalized database of common questions and answers to primarily help _future_ readers finding this on Google who may not be aware of that detail (plus, you didn't point it out either). Helping the person who originally asked the question is only a fortunate side-effect. Also, the `G` in YAGNI cannot be assumed here either, how do you know they are not _going to_ need it? Why give them a crippled, misleading tool to start with that falls apart if used generically next time? – CherryDT May 09 '22 at 09:11
  • I don't know if they gonna need it and you don't know too. You have your opinion I have mine, the purpose of this answer is to say that the arrow functions don't have their own scope, but inherits the parent scope and to show how you can get the event in the case you use an arrow function and not to force to use a simple function instead. Anyway I made an effort and edited my answer, does this answer suits you :) P.S. I didn't seen your answer – Artash Grigoryan May 09 '22 at 13:12
  • Now I upvoted it. Now the answer is a helpful addition to the other answers! And you didn't see an answer from me because I didn't need to post any, there was already an answer by Ar Rakin. – CherryDT May 09 '22 at 17:21