0

I am trying to create on-the-fly an a element and to set it an on-click function with alert. I am familiar with the closure in JavaScript so I am aware of that I cannot call it directly like doc.onclick=function() {alert(i);} since it will have the value of the last i. so I tried to call the function immediately but it's also popup the alert immediately. how can I solve this issue?

  for (var i=0; i < 5; ++i) {
       var doc = document.createElement("a");
       doc.innerHTML = i;
       doc.onclick = function(i) {alert(i);}(i);
       document.body.appendChild(doc);
   }
1
  • I think you are trying to emulate the following: doc.onclick = function () { alert(this.innerHTML); }; or doc.addEventListener('click', function () { alert(this.innerHTML); }); Commented Mar 25, 2015 at 9:40

4 Answers 4

4

You should wrap something like this:

for (var i=0; i < 5; ++i) {
       var doc = document.createElement("a");
       doc.innerHTML = i;
        (function(i){
           doc.onclick = function() {
               alert(i);
           };
        })(i)
       document.body.appendChild(doc);
   }

This way adds i to closure, DEMO

Sign up to request clarification or add additional context in comments.

Comments

3

You need to return a function in the closure here. Just calling your function immediately won't work, as you discovered.

for (var i=0; i < 5; ++i) {
   var doc = document.createElement("a");
   doc.innerHTML = i;
   doc.onclick = function(i) {
       return function(){alert(i);};
   }(i);
   document.body.appendChild(doc);
}

2 Comments

Thanks both yours and @marsh solution is working properly. but which solution is the best practice approach?
I don't think it makes a difference. Whichever is easier for you to use and understand (including looking at the code 2 years from now).
0

Change your code to this:

  for (var i=0; i < 5; ++i) {
      var doc = document.createElement("a");
      doc.innerHTML = i;
      document.body.appendChild(doc);
      doc.onclick = function() {alert(this.innerHTML);};
  }

1 Comment

also, see it live in action @ this JSFiddle jsfiddle.net/3Lv016ja it alerts the clicked number, that's what you're looking for right?
0

I'm not sure what you're trying to accomplish in the event handler but perhaps use EventTarget.addEventListener:

for (var i = 0; i < 5; ++i) {
  var doc = document.createElement("a");
  doc.innerHTML = i;
  doc.addEventListener('click', function() {
    alert(this.textContent);
  }, false);
  document.body.appendChild(doc);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.