views:

35

answers:

3

I've been working on a prototype for a client's web site and I've run into a rather significant snag. You can view the prototype here.

As you can see, the way it works is you can scroll a set of slides horizontally and, by clicking one, open a stack containing yet more slides. If you then click again on an image in that stack it opens up a lightbox. Clicking on another stack or the close button will close that stack (and open another, as case may be).

That all works great. However you get some weird behavior if you do the following:

  1. Click to open any stack.
  2. Click to open an image's light box (this works best if you click on the image that's level with the main list).
  3. Close the light box and the stack either by clicking the close button or clicking on another stack.
  4. Click back to the first stack. Instead of reopening the stack, you get the lightbox.

This confuses me as the light box should only ever be called if there is a class on the containing UL and that class is removed when the lightbox is closed. I've checked and double-checked this, it's definitely missing.

Here are the respective functions:

$("ul.hide a.lightbox").live("click",function(){
    $("ul.show").removeClass("show").addClass("hide");
    $(this).parent().parent().removeClass("hide").addClass("show");
    $("ul.hide").animate({opacity: 0.2});
    $("ul.show").animate({opacity: 1});
    $("#next").animate({opacity: 0.2});
    $("#prev").animate({opacity: 0.2});
    return false;
});

$("ul.show a.lightbox").live("click",function(){
    $(this).fancybox().trigger("click");
    return false;
});

As you can see, in order for the lightbox to be called the containing UL has to have the class of show. However, if you check it with Firebug it won't.

For those who are curious, the added .trigger("click"); is because the lightbox will require a double-click to launch otherwise.

Any idea how I can fix this?

A: 

I think the problem is that the click event is attached as soon as you add the show class, but it's not unbound once you remove it.

I'd say it'd be better to do something like this:

$("ul a.lightbox").click(function(){
  if( $(this).parent().is(".show") ){
    $(this).fancybox().trigger("click");
  }
  return false;
});
Seb
Doesn't appear to work in either case. Hmmm. (I did double-check the path.)
Which is the fun bit, it *is* firing. My guess it is't something to do with the `trigger` function. Reading up on that a bit more...
What I'm saying is that it *is* firing because when you take that `show` class out you are not unbinding the method. With this solution it doesn't matter, it'll check every time if the parent has the `show` class
Seb
A: 

Ah, I got it. Special thanks to Seb for putting me in the right direction. I added an unbind() function that was called whenever you clicked to close a stack or clicked on another stack. It's probably a bit dirty but the the event is binded and unbound every time you open and close a stack.

I'll update the prototype to reflect my changes. Thanks for the help!

A: 

The best option is to .unbind('click') after the trigger for your use (because .fancybox() attaches a direct click event handler on the link, see line 771 here), like this:

$("ul.show a.lightbox").live("click",function(){
  $(this).fancybox().trigger('click').unbind('click');
  return false;
});
Nick Craver
That's exactly what I did. I'll give you the points for the correct answer because, hey, why not?