Jon
Jon

Reputation: 467

Setting up mousedown functions using a loop

I have a whole bunch of similar list items that I want to attach mousedown() functions to. So what I would like to do is replace this:

$('#controls li[id=d1]').mousedown(function(){
    console.log('d1');
});
$('#controls li[id=d2]').mousedown(function(){
    console.log('d2');
});

with this:

var loopvar;
for (loopvar = 1; loopvar <= 2; loopvar++) {
    $('#controls li[id=d' + loopvar + ']').mousedown(function(){
        console.log('d' + loopvar);
    });
}

(This is a simplified example - I actually have lots of li's to handle.) But when I click on an li, I always get d3 on the console. The value of loopvar is 3 when the loop ends, so it looks like that is what is happening. So how can I attach the functions using a loop?

Upvotes: 0

Views: 201

Answers (3)

PSL
PSL

Reputation: 123739

Try this way:

var loopvar;
for (loopvar = 1; loopvar <= 3; loopvar++) {
    $('#controls li[id=d' + loopvar + ']').mousedown((function(loopvar){
        return function(e){
            console.log(e);
           console.log('d' + loopvar);
        }
    })(loopvar)); //You create a closure locking in the loop iteration variable
}

But ideal scenario you would just need to bind an event to the a selector either usind a common class name or using an id starts with selector. Fiddle

With startswith selector:

$('#controls li[id^=d]').mousedown(function(e){
        console.log(this.id); //here this represents the element you clicked on.
    }
);

Fiddle

Also do remember that id starts with selector is an attribute selector and would be slower compared to a class selector

Upvotes: 3

OneOfOne
OneOfOne

Reputation: 99274

  1. You should never ever do that.
  2. you should use classes instead of ids.

To use IDs anyway, try :

$('#controls li[id^="d"]').mousedown(function(){
    console.log($(this).attr('id'));
});

To use a loop, you have to use a closure to pass the var, however it's bad to assign callbacks like this, use the method above.

for (var i = 0; i < 3; ++i) {
    (function(loopvar) {
        $('#controls li[id=d' + loopvar + ']').mousedown(function(){
            console.log('d' + loopvar);
        });
    })(i);
}

Upvotes: 1

Aurelio De Rosa
Aurelio De Rosa

Reputation: 22162

If the example you've written is very similar to your actual code, I'd solve it like this:

$('#controls').find('li[id]').mousedown(function(){
    console.log(this.getAttribute('id'));
    // If you want to use jQuery...
    // console.log($(this).attr('id')); 
});

Note that $('#controls').find('li[id]') is slightly faster than $('#controls li[id]')

Upvotes: 0

Related Questions