9

I have this small problem with jquery: I need to do something like this:

$(document).ready(function(){
    links = {};
    links.a = "Link a";
    links.b = "Link b";
    links.c = "Link c";

    for (x in links){
        $("#" + x).css("border","1px solid #000");
        $("#" + x).click(function(){
            alert(x);
        });
    }
});
</script>
<div id="a">a</div><br />
<div id="b">b</div><br />
<div id="c">c</div><br />

So that when you click on div#a you will get "Link a" alert, "Link b" on div#b and so on... The problem is that if you run this code, clicking on each element will give alert("Link c") as result, it seems that only the last function variation is assigned to each div...

Of course i can hack it by editing the function to work with div's id and using $(this), but for cursiosity: is there a way to make this cycle work? By creating and assigning a new function to each element in function?

Thx in advance...

1
  • 2
    Just FYI, it's a bit neater if you chain your jQuery instead of reselecting the selector. Example: $('#'+x).css('border', '1px solid #000').click(fn); Commented Jul 23, 2009 at 15:52

9 Answers 9

33

the nice thing about jQuery is it allows chaining and binding multiple elements just like css.

$(document).ready(function(){

    $('#a,#b,#c')
        .css("border","1px solid #000")
        .bind('click',function(){
            // do something
         });

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

Comments

6

I believe this is what you're after:

$(document).ready(function(){
   links = {
      a:"Link a",
      b:"Link b",
      c:"Link c",
    };

    $.each(links, function(id,text){
      $("#"+id)
       .css("border","1px solid #000")
       .click(function(){ alert(text) })
    })
});

1 Comment

IMO this is the only sound answer other than the accepted one. By using jQuery's each method you are creating a closure on the run; for each time the function is executed. Nice work!
4

Use a closure: (a "this" solution is more elegant, but I'm posting this because a now deleted answer had a closure solution that didn't work)

$(document).ready(function(){
    links = {};
    links.a = "Link a";
    links.b = "Link b";
    links.c = "Link c";

    for (var x in links){
        $("#" + x).css("border","1px solid #000");
        $("#" + x).click(
            function(xx){ 
                return function() { alert(xx) };
            }(x)
        );
    };
});

Comments

2

Working Demo http://jsfiddle.net/FWcHv/

in you code you are calling jQuery constructor many times i.e $('#a') than $('#b') and $('#c') instead you should call like $('#a,#b,#c')

In my code i have passed through all the id's using $.each and combined them and in the next step i have used $('#a,#b,#c') stored in variable x to make the code optimized and easy.

i have also made a check that if links{} is empty it will not process using variable i

$(document).ready(function () {
    links = {};
    links.a = "Link a";
    links.b = "Link b";
    links.c = "Link c";
    i = 0;
    x = '';
    $.each(links, function (id) {
        x += "#" + id + ',';
        i++;
    });
    if (i > 0) {
        $($(x.slice(0, -1))).css("border", "1px solid #000").click(function () {
            alert($(this).text());
        });
    }
});

Comments

1
<script type="text/javascript">
$(document).ready(function(){
    $('.links').css("border","1px solid #000");
    $('.links').live('click', function() {
        alert("Link " + $(this).attr('id'));
    });
});
</script>
</head>
<body>
<div id="a" class="links">a</div><br />
<div id="b" class="links">b</div><br />
<div id="c" class="links">c</div><br />

Comments

0

You need to use "this".

$(document).ready(function(){
    links = {};
    links.a = "Link a";
    links.b = "Link b";
    links.c = "Link c";

    for (var x in links){
        $("#" + x).css("border","1px solid #000");
        $("#" + x).click(function(){
                alert("Link "+this.id+" Alert!");
        });
    }
});

Comments

0
<script type="text/javascript">
$(document).ready(function(){
    links = {};
    links.a = "Link a";
    links.b = "Link b";
    links.c = "Link c";

    for (x in links){
        $("#" + x).css("border","1px solid #000").click(function(){
                alert($(this).attr('id'));
        });
    }
});
</script>

</head>

<body>

<div id="a">a</div><br />
<div id="b">b</div><br />
<div id="c">c</div><br />

Comments

0

Seeing as you are hardcoding the elements to be effected anyways, you might as well do it this way as it's likely faster and it's cleaner, IMO:

$("#a,#b,#c").css("border","1px solid #000");
$("#a,#b,#c").click(function(){
    alert("Link "+this.id+" Alert!");
});

Edit: I didn't see the last part of your question... Sorry. You can also do this:

var links = {};
links.a = "Link a";
links.b = "Link b";
links.c = "Link c";

var ids = '';
$.each(function(key,val) {
    ids += "#"+key+","; // extra commas are ignored in jQuery
});

$(ids)
    .css("border","1px solid #000")
    .bind('click',function(){
        alert("Link "+this.id+" Alert!");
    });

Comments

0

Try using:

$(window).load(function(){

}); 

:)

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.