0

The problem is that when I create page number buttons at the bottom of the page the onclick only ever works with the last element created.

Here is what the page buttons look like:

Here is what the page buttons look like

    for(var i = 0; i < numberOfPages; i++) {
        if(Math.floor((((startIndex + 1) / 10) + 1)) == (i + 1)) {
            var newElement = document.createElement("u");
            document.getElementById("imagesNav").appendChild(newElement);
            newElement.id = "imagesNavU";
            var newElement = document.createElement("a");
            document.getElementById("imagesNavU").appendChild(newElement);
            var str = "page" + (i + 1);
            newElement.innerHTML = i + 1;
            newElement.onclick=function(){currentPageNumber(str);};
        } else {
            var newElement = document.createElement("a");
            document.getElementById("imagesNav").appendChild(newElement);
            var str = "page" + (i + 1);
            newElement.innerHTML = i + 1;
            newElement.onclick=function(){currentPageNumber(str);};         
        }
        if(i + 1 != numberOfPages) {
            document.getElementById("imagesNav").innerHTML += "&nbsp;&nbsp;";
        }
    }
}

The first if statement just puts underline tags on if that element is the current page.

Edit: The problem has been solved. Thank you to everyone for their help!

mtagius
  • 23
  • 5
  • Would be much easier to help if you first included the code `currentPageNumber()` function. – etherealite Jun 30 '16 at 00:33
  • 1
    @etherealite That function is irrelevant, the problem is that all the closures are using the same `str` variable. – Barmar Jun 30 '16 at 00:44
  • @Barmar Would the function still be called though? The function is only ever called with the last button. – mtagius Jun 30 '16 at 11:06
  • I think you're confused about what's going wrong. The function is called for all the links, but they all call it with the same `str` argument, which comes from the last iteration of the loop. – Barmar Jun 30 '16 at 14:00
  • An unrelated problem is that you seem to be creating multiple elements with `id=imagesNavU`, every time the `if` succeeds. IDs should be unique. I'm not sure why you need that ID, since you have the new `` element in a variable and you could just use that variable to append the child (or course, you'll need to use a different variable name for the `` element). – Barmar Jun 30 '16 at 14:03
  • @Barmar That may be true, but I put a breakpoint in the function the onclick calls and the breakpoint is only ever triggered by the last element. – mtagius Jul 01 '16 at 01:27

1 Answers1

0

The problem is with this part of the loop:

    if(i + 1 != numberOfPages) {
        document.getElementById("imagesNav").innerHTML += "&nbsp;&nbsp;";
    }

This is re-parsing all the HTML in the imagesNav element. This creates new <a> elements, which don't have the onclick bindings that the previous ones had.

Instead, you can append a <span> element containing the spaces.

var numberOfPages = 3;
var startIndex = 0;

for (var i = 0; i < numberOfPages; i++) {
  if (Math.floor((((startIndex + 1) / 10) + 1)) == (i + 1)) {
    var newElement = document.createElement("u");
    document.getElementById("imagesNav").appendChild(newElement);
    newElement.id = "imagesNavU";
    var newElement = document.createElement("a");
    document.getElementById("imagesNavU").appendChild(newElement);
    var str = "page" + (i + 1);
    newElement.innerHTML = i + 1;
    newElement.onclick = function() {
      currentPageNumber(str);
    };
  } else {
    var newElement = document.createElement("a");
    document.getElementById("imagesNav").appendChild(newElement);
    var str = "page" + (i + 1);
    newElement.innerHTML = i + 1;
    newElement.onclick = function() {
      currentPageNumber(str);
    };
  }
  if (i + 1 != numberOfPages) {
    var span = document.createElement('span');
    span.innerHTML = '&nbsp;&nbsp;';
    document.getElementById("imagesNav").appendChild(span);
  }
}

function currentPageNumber(str) {
  alert(str);
}
<div id="imagesNav">

</div>

Another way to do it is with insertAdjacentHTML, which adds HTML to an element without re-parsing what's already in it.

    document.getElementById("imagesNav").insertAdjacentHTML('beforeend', '&nbsp;&nbsp;');

You should also see JavaScript closure inside loops – simple practical example because the way you're using the str variable, all the click handlers will use the value from the last iteration of the loop.

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • note that clicks work but all return `Page3`. Correct form is `function currentPageNumber(str) { return function(){alert(str);}}` and `newElement.onclick = currentPageNumber(str);` – Alex Kudryashev Jul 01 '16 at 02:16
  • @AlexKudryashev That's the problem I pointed out in the last paragraph of the answer. – Barmar Jul 01 '16 at 02:27
  • 1
    @AlexKudryashev That's what I originally thought his whole problem was, so I closed the question as a duplicate. Then I saw the other problem, so I reopened it, and just added the link as additional information, since it's not directly related to the question he asked. – Barmar Jul 01 '16 at 02:29
  • @Barmer You are the best! This solved my problem. You guys are great! – mtagius Jul 01 '16 at 10:23