mtagius mtagius - 5 months ago 7
HTML Question

Adding an onclick event to a new html element only working on the last element

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!

Answer

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.