0

This is simplified code that demonstrates my issue:

    class TestClass {
    constructor(label) {
        this.uid = Math.floor(Math.random() * 1000);
        this.label = label;
        this.btnId = "btn-" + this.uid;
        let tableBody = document.getElementById("the-table").innerHTML;
        tableBody += `<tr><td id=${this.uid}><button id=${this.btnId}>${this.label}</button></td></tr>`
        document.getElementById("the-table").innerHTML = tableBody;

        document.getElementById(this.btnId).onclick = function() {
            incr();
        }
    }
}

let a = new TestClass("+1");
let b = new TestClass("+1");
let c = new TestClass("+1");

let x = 1;

function incr() {
    x += 1;
    console.log(x);
}

When I run it in browser, only the button/class to last assigned variable ("c" in this case) works, other buttons do nothing. I guess I am missing something obvious...

I am interested in solution with vanilla JS. I saw similar question which was solved with jQuery "on" method, but I did not test it.

  • `addEventListener` – user120242 Jun 05 '20 at 22:15
  • you are destroying your button instances when you overwrite innerHTML, invalidating your onclick handlers. Either use document.createElement('tr') and appendChild or wait until you are finished building and writing to innerHTML before trying to attach event listeners. or embed onclick directly as a string – user120242 Jun 05 '20 at 22:25
  • Thank you very much. Do you care to explain in more detail how am I destroying previous button instances, considering I am appending new row to existing innerHTML? I don't get it... – xitachi Jun 06 '20 at 05:51
  • You are overwriting innerHTML. `.innerHTML += 1` is the same as `.innerHTML = innerHTML + 1` which overwrites the entire HTML string enclosed, which forces it to re-render the entire element's contents. Thus the referenced DOM elements that existed are destroyed and recreated. Optimizations in rendering engines might preserve the objects internally, but to maintain spec compliance they would have to dereference all previous references so that it behaves like they were destroyed – user120242 Jun 06 '20 at 05:52
  • Thank you once again. It is perfectly clear and makes perfect sense. – xitachi Jun 06 '20 at 05:56

0 Answers0