I love fancybox. It’s a great and flexible jQuery lightbox, but I decided there were a couple of things I needed it to do that it doesn’t, so I dived into the code head first and added a couple of features. Be warned that you need to edit the file jquery.fancybox-1.3.1.js to implement them.
Combined add and fire / show / open
Yes I know you can do this with $.fancybox(content, options)
It’s tough to add the fancybox listener and fire it at the same time, for example onclick or using a live event. That annoyed me in some circumstances. Previously I have resorted to adding fancybox to anchors on hover so it could fire onclick:
$('a.fancybox').mouseover(function() { $(this).fancybox(); });
But that’s not cool. So I added the option to the core.
// replace $.fn.fancybox = function(options){ $(this) // with $.fn.fancybox = function(options) { if(options === 1) { options = {now:true}; } $(this)
and
// replace }); return this; }; $.fancybox = function(obj) { // with }); if(options.now) { $(this).click(); } return this; }; $.fancybox = function(obj) {
You can fire it in two ways. If you are also including options then fire it on add by including now:true as an option like:
$(this).fancybox({ now:true, showCloseButton : false, enableEscapeButton : false });
or if you are not setting options then fire it on add like:
// note the (1) $(this).fancybox(1);
Either way, fancybox should now open / fire / show as soon as you attach it to an element.
And for my next trick….
Stop lightbox vertical movement
The default behavour is for fancybox to centre itself on vertical or horizontal scroll or window resize. I needed (see the final tweak) the box to stay still vertically even if I scrolled, but stay centre horizontally.
To implement this I made this change:
// replace to.top = view[3] + ((view[1] - ((wrap.height() - titleh) + (shadow * 2 ))) * 0.5); to.left = view[2] + ((view[0] - (wrap.width() + (shadow * 2 ))) * 0.5); to.top = Math.max(view[3] + margin, to.top); to.left = Math.max(view[2] + margin, to.left); // with if(currentOpts.centerTopOnScroll) { to.top = view[3] + ((view[1] - ((wrap.height() - titleh) + (shadow * 2 ))) * 0.5); to.top = Math.max(view[3] + margin, to.top); } to.left = view[2] + ((view[0] - (wrap.width() + (shadow * 2 ))) * 0.5); to.left = Math.max(view[2] + margin, to.left);
and then add that new option to the defaults:
// replace centerOnScroll : false, // with centerOnScroll : false, centerTopOnScroll : true,
You can then include the new option centerTopOnScroll:false to keep the top position static even on horizontal scroll.
The final change I have made is:
Clone the position and dimensions of an element
This tweak allows you to specify an element to clone. The original lightbox created will then be in the position and have the dimensions of the specified element. I bolded original because you can then alter the dimensions and positions yourself using jquery or by updating the content.
To implement this:
// replace final_pos = fancybox_get_zoom_to(); fancybox_process_title(); // with if(currentOpts.clonePosition) { // get final_pos from the element we are cloning var pos = currentOpts.elementToClone.offset(); final_pos = { height:currentOpts.elementToClone.outerHeight(), width:currentOpts.elementToClone.outerWidth(), left:pos.left, top:pos.top }; } else { final_pos = fancybox_get_zoom_to(); } fancybox_process_title();
and
// replace (after the previous change for vertical scroll) to.left = view[2] + ((view[0] - (wrap.width() + (shadow * 2 ))) * 0.5); to.left = Math.max(view[2] + margin, to.left); // with if(currentOpts.clonePosition) { to.left = currentOpts.elementToClone.offset().left } else { to.left = view[2] + ((view[0] - (wrap.width() + (shadow * 2 ))) * 0.5); } to.left = Math.max(view[2] + margin, to.left);
You then have the choice of including new options:
clonePosition:true elementToClone:$('#element') // a jquery element
So there you have it.
Combined add and fire / show / open
Stop lightbox vertical movement
Clone the position and dimensions of an element