Reputation: 7673
How can I simplify these statements, instead of having to count all the way upt to 34 and having 34 separate statements…..
$('a#timeline-2010-lnk1').click(function() {
$('#timeline-2010-1').show();
return false;
});
$('a#timeline-2010-lnk2').click(function() {
$('#timeline-2010-2').show();
return false;
});
$('a#timeline-2010-lnk3').click(function() {
$('#timeline-2010-3').show();
return false;
});
$('a#timeline-2010-lnk4').click(function() {
$('#timeline-2010-4').show();
return false;
});
Upvotes: 5
Views: 219
Reputation: 236202
You can use a for
loop like Luca
suggested earlier (deleted). But you have to create a helper "self-invoking function" in order to keep things right:
for(var i=1; i<=34; i++) {
(function(index){
$('a#timeline-2010-lnk'+index).click(function() {
$('#timeline-2010-'+index).show();
return false;
});
})(i);
}
Why is that? Javascript only has function scope
and not a block scope
like in most other C-like languages. So i
is not bound to the scope of the for-loop
THEREFORE the closure functions
you're creating as event handler to click
will all reference to the same i
.
By creating a new function which invokes itself at runtime, you can workaround this issue.
Upvotes: 1
Reputation: 344803
$("a[id^=timeline-2010-lnk]").live("click", function () {
var num = this.id.split(/-(?:lnk)?/).pop();
$('#timeline-2010-'+num).show();
return false;
});
More efficient because it uses delegate()/live(). Instead of attaching many click handlers, a single handler is placed on the common ancestor node, which click events will bubble up to.
As @rochal pointed out, even more appropriate might be to use a single class name for all the elements and taking advantage of the relationship between the two elements (via parent/etc). However, if you can, you should still consider using live() or delegate() for the handler.
Upvotes: 9
Reputation: 91149
Use a startswith attribute selector with $.each
$('a[id^=timeline-2010-lnk]').each(function () {
var idx = $(this).attr('id').match(/\d+$/);
if (idx !== null) {
$(this).click(function () {
$('#timeline-2010-' + idx[0]).show();
return false;
});
}
});
Upvotes: 0
Reputation: 7781
Add a common className to every element:
<a href="#" id="timeline-2010-lnk1" class="clicker">Text 1</a>
<a href="#" id="timeline-2010-lnk2" class="clicker">Text 2</a>
<a href="#" id="timeline-2010-lnk3" class="clicker">Text 3</a>
<a href="#" id="timeline-2010-lnk4" class="clicker">Text 4</a>
<a href="#" id="timeline-2010-lnk5" class="clicker">Text 5</a>
...
Then, you could simplify your HTML, and get rid of IDs all together:
<a href="#" class="clicker">Text 1</a>
<a href="#" class="clicker">Text 2</a>
<a href="#" class="clicker">Text 3</a>
<a href="#" class="clicker">Text 4</a>
<a href="#" class="clicker">Text 5</a>
...
Then, all you have to do is:
$('.clicker').click(function() {
$(this). /* parent? sibling? I'd have to see your code */ .show();
return false;
});
Node regarding my comment in the code:
I assume that #timeline-2010-[X]
is some sort of div you want to show, so instead of using IDs again, apply a class and use .siblings()
or .find()
etc.
Upvotes: 4
Reputation: 15231
As long as you're using jQuery, try something like this:
$('a[id^=timeline-2010-lnk]').click(function() {
var id = '#' + this.id.replace(/lnk/, '');
$(id).show();
return false;
});
This will grab all links whose id attribute starts with "timeline-2010-lnk" and attach a click event. You get the corresponding id by simply removing the "lnk" part from the link's id.
Here's a doc for the "attribute starts with" selector: http://api.jquery.com/attribute-starts-with-selector/
Additionally, here's a simple demo showing this method in action: http://jsfiddle.net/eL3Yw/
Upvotes: 0