0

Hi im new to JavaScipt and testing my code. I want to add event listener to all buttons and make later on function that will perform different operation based on which button was clicked. So first im trying to test if i can add event listener to all of them via loop which i never tried before and then see if they react to click.But neither console.log nor alert output anything. What am i doing wrong?

Here is code:

<!DOCTYPE html>

<html lang="en">
    <head>
        <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@500&display=swap" rel="stylesheet">
        <link href="styles.css" rel="stylesheet">
        <title>Trivia!</title>
        <script>
           var a=document.getElementsByTagName("button");


    for(var i = 0; i < a.length; i++) {

        a[i].addEventListener('click', function(){
        console.log(a[i]);
        });
        }
        </script>
    </head>
    <body style="background-color:blue">
        <div class="header">
            <h1>Trivia!</h1>
        </div>

        <div class="container">
            <div class="section">
                <h2>Part 1: Multiple Choice </h2>
                <hr>
                <h3>What song was played that day?</h3>
                <div >
                    <button>A</button>
                    <button>B</button>
                    <button>C</button>
                </div>
            </div>

            <div class="section">
                <h2>Part 2: Free Response</h2>
                <hr>
                <>
            </div>
        </div>
    </body>
</html>
  • 2
    Your script runs before the browser has seen the rest of the document, so there are no buttons. – Pointy Nov 16 '22 at 11:59
  • 1
    Also use `let` instead of `var` – Pointy Nov 16 '22 at 12:00
  • You can wrap it with 'document.addEventListener("DOMContentLoaded", function() { //your code })' so the elements are loaded when the script is being executed. That should work. – Mees Kluivers Nov 16 '22 at 12:06
  • @MeesKluivers - You can, but there's no real reason to if you control the placement of the `script` tag (and if you don't, you need to handle the case where your script has been added after that event fired). Just use `type="module"` (the modern way) or `defer` on the `script` tag, or put the `script` tag at the end of the body just before the closing `

    `.

    – T.J. Crowder Nov 16 '22 at 12:07
  • @T.J.Crowder thanks for help. The error is now "undentified" for some reason im not sure why – 21CenturyBoy Nov 16 '22 at 12:56
  • @21CenturyBoy - What does that mean? Can you copy and paste the actual error to your question? – T.J. Crowder Nov 16 '22 at 12:58
  • @T.J.Crowder sorry i misspelled its actually just "undefined" but there is unfortunately no additional information about error displayed just undefined and every time i click a button once actual page is loaded counter of undefined is increased by 1 – 21CenturyBoy Nov 16 '22 at 13:05
  • @​21CenturyBoy - That means apparently you're still using `var` in the loop. See @Pointy's comment above, and [the second question](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) listed in the list of previous questions on this topic. By the time the event handler runs, `i` will be beyond the end of the collection you got from `getElementsByTagName`, so `a[i]` is `undefined`. Using `let` for `i` fixes it because the semantics of `let` and `var` are different. (`var` has no place in modern JavaScript, don't use it in new code. :-) ) – T.J. Crowder Nov 16 '22 at 13:07
  • @T.J.Crowder thank you it fixed the problem.Its strange as beginner coming from c to JavaScript i feel like deer in the headlights often its as if my previous knowledge hinders me rather than helping me. As for scope of let vs var and always using let. Why is it better to use let ? For instance wouldn't it be better to declare variable with var in function if you modify it multiple times for instance first via if statement then via loop? Because sometimes in function you operate on value more than once? – 21CenturyBoy Nov 16 '22 at 13:36
  • @21CenturyBoy - There's no reason you can't do that, just do it with `let` instead of `var`. :-) The chief advantages of `let` (in no particular order) are 1. block scope (esp. useful in loops); 2. the Temporal Dead Zone, preventing you from using the variable prior to the declaration;. 3. redeclaration is disallowed with `let` (and `const`), but not with `var`. (If you're keen on knowing more, I dedicate an entire chapter (Chapter 2) to `let` and `const` in my recent book [*JavaScript: The New Toys*](https://thenewtoys.dev). :-D ) – T.J. Crowder Nov 16 '22 at 13:38
  • BTW, I hear you about C vs. JavaScript. In my case, I had C, C++, and Java in my background (along with other unrelated languages) before really starting seriously with JavaScript. JavaScript is so different despite being superficially similar it can really trip you up. (And yet, when you "grok" it, it's arguably simpler -- though some of the bad early decisions and bugs [`typeof null` being `"object"` is literally a bug from the original implementation that ended up being encoded in the spec] are a pain.) – T.J. Crowder Nov 16 '22 at 13:44
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/249668/discussion-between-21centuryboy-and-t-j-crowder). – 21CenturyBoy Nov 16 '22 at 13:47
  • @21CenturyBoy - Sorry, I don't do the chat thing, no matter what SO says. :-) – T.J. Crowder Nov 16 '22 at 13:55
  • @T.J.Crowder Np well overall do you have other book or recommendation how to truly understand modern abstracted languages from ground up coming from something like C – 21CenturyBoy Nov 16 '22 at 14:03
  • If you have the basics of JavaScript under your belt, I think I do a good job explaining the new features and along the way explaining some of the underpinning stuff. The usual "from the beginning" recommendation is David Flanagan's *JavaScript: The Definitive Guide* which is what I started with (but it's been revised since then). Axel Rauschmayer (for example: https://exploringjs.com) is pretty good for bare-bones, no-nonsense explanations. I would steer clear of Douglas Crockford and Kyle Simpson -- too much opinion presented as fact. – T.J. Crowder Nov 16 '22 at 14:14

0 Answers0