TeddTedd
TeddTedd

Reputation: 1

JQuery: using .LIVE problems

I have the following JQuery code:

$("#myDIV li:eq(0)").live('click',function(){ funcA(); });
$("#myDIV li:eq(1)").live('click',function(){ funcB(); });
$("#myDIV li:eq(2)").live('click',function(){ funcC(); });
$("#myDIV li:eq(3)").live('click',function(){ funcD(); });

And realized it's really inefficient.

So I tried the following, which I believe is much more effect; however, the code does not work:

var tab_node = $("#myDIV li");
tab_node.eq(0).live('click',function(){ funcA(); });
tab_node.eq(1).live('click',function(){ funcB(); });
tab_node.eq(2).live('click',function(){ funcC(); });
tab_node.eq(3).live('click',function(){ funcD(); });

Any idea how I can make my code more efficient while also work?

UPDATE:

From the answers below, it sounds like these two statements are not equalavent.

New Question: Is there any way to run my original code more efficient?

Upvotes: 0

Views: 317

Answers (4)

Luca Filosofi
Luca Filosofi

Reputation: 31173

$('#myDIV li').live('click' , function() {
    var index = $(this).index();
    if (index == 0) funcA();
    if (index == 1) funcB();
    if (index == 2) funcC();
    if (index == 3) funcD();
});

Edit: Even more fun ..

(function () {
    var funcs = [funcA, funcB, funcC, funcD];
    $('#myDIV li').live('click' , function() {
        funcs[$(this).index()](); // should check array boundary, but.. meh
    });
}());

EDIT 2

and of course if you want observe only the first 4 LI's use this:

 $('#myDIV li:lt(4)')

Upvotes: 1

Jerod Venema
Jerod Venema

Reputation: 44632

From the caveats in the docs:

DOM traversal methods are not fully supported for finding elements to send to .live(). Rather, the .live() method should always be called directly after a selector, as in the example above.

The example above shows:

$('.hoverme').live('mouseover mouseout', function(event) {
  if (event.type == 'mouseover') {
    // do something on mouseover
  } else {
    // do something on mouseout
  }
});

You need to apply to the selector, not the DOM. Is there a particular reason you find your original code inefficient? It should be just fine. The only suggestion I'd have is to delay the filtering:

$("#myDIV li").live('click', function(e){
   // analyze the event target here to determine the actual element
   // to do so, use $(e.target)
});

By doing this, you've only got 1 live event, and the selector is simpler too. The tradeoff is handling the switch statement for each target element in your own code.

Upvotes: 0

TM.
TM.

Reputation: 111027

Your original code doesn't really make much sense to me if you are going to be adding new li items on the fly.

It probably isn't going to behave how you think it will.

The first 4 things will get the event handlers you want, anything added later wont, unless it is added so that it appears in the top 4 spots in the list. But if things are added at the top of the list, the original items that used to be there won't be unbound/reassigned.

For example:

<ul>
    <li>A</li> <!-- will call funcA when clicked -->
    <li>B</li> <!-- will call funcB when clicked -->
    <li>C</li> <!-- will call funcC when clicked -->
    <li>D</li> <!-- will call funcD when clicked -->
</ul>

Now if you add a new li anywhere under that, it won't get a click handler (in which case you don't need live). If you add a new one in the middle, this will happen:

<ul>
    <li>A</li> <!-- will call funcA when clicked -->
    <li>B</li> <!-- will call funcB when clicked -->
    <li>New thing that got added</li> <!-- will call funcC when clicked -->
    <li>C</li> <!-- will call funcC when clicked -->
    <li>D</li> <!-- will call funcD when clicked -->
</ul>

Why don't you explain what you want to happen on the page so that we can help?

Upvotes: 0

Matt
Matt

Reputation: 44058

The first code works because it's binding the event to a live selector.

The second code is applying a live to a specific element (the .eq(x) returns a jQuery object with a collection of just that element) - it's not applying it to a selector to listen to in the future.

With the way you have it set up (each <li> calling a different function), I can't really think of an elegant way to approach the issue.

Also, why are you using live for such a specific selection? Are those <li>'s removed/added as the page lives on?

Unless you truly need live, I would do it like so..

var tab_node = $("#myDIV li");
tab_node.eq(0).click(funcA);
tab_node.eq(1).click(funcB);
tab_node.eq(2).click(funcC);
tab_node.eq(3).click(funcD);

Upvotes: 0

Related Questions