1

I want to add a link dynamically and attach "onclick" event on it. Here's a simplified version of what I have:

for (var i = 0; ....) {
    var a1 = document.createElement("a");
    a1.innerHTML = "My link123";
    a1.addEventListener("click", function(event) {
      myFunc(someArray[i].property1, event);
      // alert("test123");
    });

    var p1 = document.createElement("p");
    var sp1 = document.createElement("span");
    //..........

    divContainer.innerHTML += a1.outerHTML + p1.outerHTML + sp1.outerHTML;
 }

But it doesn't trigger the "click" event when I click on it.

update:

after it's created and I click on it, I get: myFunc(someArray[i].property1, event); -- Cannot read property 'property1' of undefined

I guess it's something related to how clojures are evaluated.

update2

I've tried this:

a1.addEventListener("click", function(event) {
  (function(i2){
    myFunc(i2, event);
  })(myArray[i].property1);
});

But it said at runtime when I clicked on it "property1 isn't defined"; How can I fix that?

Kooooro
  • 443
  • 1
  • 6
  • 15
  • 3
    You should `.appendChild(a1)` if you want the click event to stay intact, rather than copying the HTML produced. – Heretic Monkey Dec 02 '16 at 16:28
  • 1
    This will also be relevant: [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/q/750486/218196) – Felix Kling Dec 02 '16 at 16:29
  • @MikeMcCaughan, actually I have other html elements created dynamically along with it, for them I'm using "outerHTML". How can I combine these 2 approaches? – Kooooro Dec 02 '16 at 16:29
  • 1
    @Joshimari: So what? Serializing the DOM element to HTML will loose all bound event handlers. Nothing you can do about that. *"How can I combine these 2 approaches?"* Don't. Use the DOM API to mutate the document. Call `divContainer.appendChild` for each new child. – Felix Kling Dec 02 '16 at 16:30

1 Answers1

2
divContainer.innerHTML += a1.outerHTML + p1.outerHTML + sp1.outerHTML;

You are serialising the DOM nodes (both the new ones and the ones already in divContainer) to HTML, which doesn't include the event listeners, and then creating new DOM nodes from the HTML.

Use appendChild and friends instead.

divContainer.appendChild(a1);
divContainer.appendChild(p1);
divContainer.appendChild(sp1);
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • @Joshimari — That's a different problem. As Felix said: See http://stackoverflow.com/q/750486/218196 – Quentin Dec 02 '16 at 16:44
  • @Joshimari — You're still trying to read `i` inside the click event handler. By the time the click happens, `i` will have changed. Read [this question and its answers](http://stackoverflow.com/q/750486/218196) again. – Quentin Dec 02 '16 at 16:52
  • You capture the value of `i` when you go around the loop instead of when you click. – Quentin Dec 02 '16 at 17:09
  • I know. How should I fix it? Show me an example. – Kooooro Dec 02 '16 at 17:16
  • There are examples in the linked question. – Quentin Dec 02 '16 at 18:03