3

I would like to use the click() function of jQuery within a for loop in order to make three HTML elements clickable. I created a simple test case:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.3.min.js" />
  <script type="text/javascript">
    $(window).load(function() {
      function loadContent(){
        var values = ['a','b','c'];
        for (var i = 0; i < values.length; ++i) {
          var id = values[i];
          alert(id);
          $('#' + id).click(function() {
            function2(id);
          });
        }
      }

      function function2(id) {
        // do some fancy stuff like...
        alert(id);
      }

      loadContent();
    });
  </script>
</head>
<body>
  <div id="map">
    <a id="a">a</a>
    <a id="b">b</a>
    <a id="c">c</a>
  </map>
</body>

As you can see, I would like to display the character 'a' if I click on 'a' (a), display 'b' while clicking on 'b', and so on. Unfortunately, the character 'c' is displayed while clicking on 'a'. No other events are triggered. I do not see the mistake I commit.

I don't bother if this code is efficient or not. I just want to know, why click() does not act as expected in this context. Thanks in advance for any hints or solution.

2
  • 2
    There should be a complete Stackexchange site devoted to this question :-) Commented Nov 1, 2010 at 18:37
  • Why hasn't this made it to the JavaScript FAQ yet? Commented Nov 1, 2010 at 19:11

5 Answers 5

2

Each one of the "click" handlers you create will reference that same, single variable "id". You'll note that it changes on each iteration of the loop. When the loop is done, it'll be pointing at the very last one.

You need to set up the handlers differently:

    for (var i = 0; i < values.length; ++i) {
      var id = values[i];
      alert(id);
      $('#' + id).click((function(id) {
        return function() { function2(id); };
      })());
    }

The block constructed for your for loop does not create a new lexical scope, as it does in some languages. In Javascript, that "id" variable is a local variable to the "loadContent" function. Each one of the "click" handlers in your version references that same variable.

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

4 Comments

This isn't the only issue, the id attributes are a problem as well.
Well it sure seems like it'd be the issue if the rest of the code weren't all broken. I assumed he just typed it in wrong. Why else would he always see "c"? edit - ah good edit :-)
yeah sorry you're correct this is also an issue, but not the simplest fix IMO, this.id would work in this case, and be cheaper :)
@Nick yes of course in this case that'd be true. Still, if that's how he fixed this one it'd take another SO question to confront the closure problem!
0

You have a few issues here:

  • All your id attributes are set to id="a" so you're re-binding the first element each time (this is the main issue with your click handler). Set the second to id="b" and the third to id="c".
  • <script> elements can't be self-closing, our jQuery include needs fixing from /> to ></script>
  • </map> should be </div>
  • You're re-using id scoped to the function, but there's no need you might as well use function2(this.id) as the simplest fix for your case.

You can test the updated/working version here.

Comments

0

You have 3 elements with the same ID. An ID is supposed to be unique.

Comments

0

All of your id's are set to 'a'. Try setting your id's to a,b,c

Comments

0

The ids of the <a></a> tags are all "a" in your example.

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.