0

This is a simple javascript code. I'm creating 5 divs in script and populate an 'onclick' event for each. However, all of them give me the id of the last one. Any idea why this behavior occurring? Many thanks.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Test Page</title>
    <style type="text/css">
        .divImgPoint {
            float: left;
            border-radius: 50%;
            width: 15px;
            height: 15px;
            margin-left: 5px;
            margin-right: 5px;
            border: ridge 2px #c73756;
        }

        .divTest {
            position: absolute;
            width: 100px;
            height: 100px;
            top: 200px;
            left: 100px;
            border: 1px solid red;
        }
    </style>
    <script type="text/javascript">
        function createNewDivs() {
            var divFixed = document.getElementById('divFixed');
            var newDiv;

            for (xI = 0; xI < 5; xI++) {
                newDiv = document.createElement('div');
                newDiv.id = "newDiv_" + xI;
                newDiv.className = "divImgPoint";
                newDiv.onclick = () => { alert(newDiv.id + " | " + xI); }
                divFixed.appendChild(newDiv);
            }
        }
    </script>
</head>
<body>
    <div id="divFixed">
    </div>
</body>
</html>
<script type="text/javascript">
    window.addEventListener('load', () => { createNewDivs(); });
</script>
Sdx.1969
  • 13
  • 1
  • 6
  • It's working in your example. – Luca Kiebel Feb 24 '22 at 10:16
  • I'm running it in the code snippit, on the 5 circles I'm getting 'newDiv_4 | 5' via the alert. I should be getting something like 'newDiv_0 | 0' for the first circle, 'newDiv_1 | 1' for the next one and so on. – Sdx.1969 Feb 24 '22 at 10:20
  • @Liam, nope it's unrelated, since the circles are created, however the onclick behavior that is the question here. – Sdx.1969 Feb 24 '22 at 10:24
  • Instead of using a single `var newDiv` use `const newDiv = document.createElement('div');` (or `let`) inside the for loop. This will keep the reference inside the onclick handler. Otherwise the click handler will use the one newDiv that exists, which is the last one you created. Also, don't use arrow functions unless you know how they behave differently from normal ones. Because another way to solve this is to use a regular `function` and `this.id` –  Feb 24 '22 at 10:24
  • Duplicate: [What's the difference between using "let" and "var"?](https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var) –  Feb 24 '22 at 10:25

1 Answers1

-1

Put let newDiv; inside loop.

Like

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Test Page</title>
    <style type="text/css">
        .divImgPoint {
            float: left;
            border-radius: 50%;
            width: 15px;
            height: 15px;
            margin-left: 5px;
            margin-right: 5px;
            border: ridge 2px #c73756;
        }

        .divTest {
            position: absolute;
            width: 100px;
            height: 100px;
            top: 200px;
            left: 100px;
            border: 1px solid red;
        }
    </style>
    <script type="text/javascript">
        function createNewDivs() {
            var divFixed = document.getElementById('divFixed');
            

            for (xI = 0; xI < 5; xI++) {
                let newDiv;
                newDiv = document.createElement('div');
                newDiv.id = "newDiv_" + xI;
                newDiv.className = "divImgPoint";
                newDiv.onclick = () => { alert(newDiv.id + " | " + xI); }
                divFixed.appendChild(newDiv);
            }
        }
    </script>
</head>
<body>
    <div id="divFixed">
    </div>
</body>
</html>
<script type="text/javascript">
    window.addEventListener('load', () => { createNewDivs(); });
</script>
divyesh makvana
  • 384
  • 1
  • 5
  • Put **LET** newDiv inside the loop, as your code does. You could also use this opportunity to fix the snippet. Also, this is a duplicate. Keep in mind that a question should be new (not going to happen) and useful for future readers. SO isn't a chat forum. –  Feb 24 '22 at 10:24
  • @Sdx.1969 I didn't post an answer, this is a dupe and marked as such, you're welcome though :) –  Feb 24 '22 at 10:35