Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery combine statements?

Tags:

jquery

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;
  });
like image 623
tony noriega Avatar asked Sep 03 '10 15:09

tony noriega


3 Answers

$("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.

like image 145
Andy E Avatar answered Nov 11 '22 03:11

Andy E


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.

like image 4
rochal Avatar answered Nov 11 '22 02:11

rochal


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.

like image 1
jAndy Avatar answered Nov 11 '22 02:11

jAndy