When you have a site that uses Slimbox V2 and upgrade to jQuery 1.9.1 you get a strange behavior. The semitransparent overlay layer comes in front of your image instead of behind it.
Before the upgrade, I used jQuery 1.8 and everything was working fine. Nothing else changed on the site. How to solve the issue without downgrading jQuery?
The reason it doesn't work is that jQuery 1.9 changes the way .after()
works, and the complicated code in the original lightbox that I show below uses .after()
in the old way (assumes it adds the new element to the set of elements returned, whereas the new .after()
doesn't.)
You can easily fix it by changing the order, so instead of:
$('.....).appendTo($('body'));
you just do:
$('body').append($('...);
However beware. The code below has been changed by me to put the data section above the picture rather than below it, and that needs other changes (you need to add the height of the data section in the size_container
function). Nevertheless, it's a demonstration of how the problem can be fixed—and is working. See the web site I am working on
Lightbox.prototype.build = function() {
var $lightbox,
_this = this;
$('body').append($("<div>", {
id: 'lightboxOverlay'
}),$('<div/>', {
id: 'lightbox'
}).append($('<div/>', {
"class": 'lb-outerContainer'
}).append($('<div/>', {
"class": 'lb-dataContainer'
}).append($('<div/>', {
"class": 'lb-data'
}).append($('<div/>', {
"class": 'lb-details'
}).append($('<span/>', {
"class": 'lb-caption'
}), $('<span/>', {
"class": 'lb-number'
})), $('<div/>', {
"class": 'lb-closeContainer'
}).append($('<a/>', {
"class": 'lb-close'
}).append($('<img/>', {
src: this.options.fileCloseImage
}))))),$('<div/>', {
"class": 'lb-container'
}).append($('<img/>', {
"class": 'lb-image'
}),$('<div/>', {
"class": 'lb-nav'
}).append($('<a/>', {
"class": 'lb-prev'
}), $('<a/>', {
"class": 'lb-next'
})), $('<div/>', {
"class": 'lb-loader'
}).append($('<a/>', {
"class": 'lb-cancel'
}).append($('<img/>', {
src: this.options.fileLoadingImage
})))))));
I fixed it in version 2.05.
Here is the diff with the change in the code.
Hm...
Fixed Lightbox2 jQuery 1.9.1 - http://www.cybernova.net/javascripts/lightbox.js
Here is the fix I found.
/*
Slimbox v2.04 - The ultimate lightweight Lightbox clone for jQuery
(c) 2007-2010 Christophe Beyls <http://www.digitalia.be>
MIT-style license.
*/
(function(w){var E=w(window),u,f,F=-1,n,x,D,v,y,L,r,m=!window.XMLHttpRequest,s=[],l=document.documentElement,k={},t=new Image(),J=new Image(),H,a,g,p,I,d,G,c,A,K;w(function(){w("body").append(w([H=w('<div id="lbOverlay" />').click(C)[0],a=w('<div id="lbCenter" />')[0],G=w('<div id="lbBottomContainer" />')[0]]).css("display","none"));g=w('<div id="lbImage" />').appendTo(a).append(p=w('<div style="position: relative;" />').append([I=w('<a id="lbPrevLink" href="#" />').click(B)[0],d=w('<a id="lbNextLink" href="#" />').click(e)[0]])[0])[0];c=w('<div id="lbBottom" />').appendTo(G).append([w('<a id="lbCloseLink" href="#" />').click(C)[0],A=w('<div id="lbCaption" />')[0],K=w('<div id="lbNumber" />')[0],w('<div style="clear: both;" />')[0]])[0]});w.slimbox=function(O,N,M){u=w.extend({loop:false,overlayOpacity:0.8,overlayFadeDuration:400,resizeDuration:400,resizeEasing:"swing",initialWidth:250,initialHeight:250,imageFadeDuration:400,captionAnimationDuration:400,counterText:"Image {x} of {y}",closeKeys:[27,88,67],previousKeys:[37,80],nextKeys:[39,78]},M);if(typeof O=="string"){O=[[O,N]];N=0}y=E.scrollTop()+(E.height()/2);L=u.initialWidth;r=u.initialHeight;w(a).css({top:Math.max(0,y-(r/2)),width:L,height:r,marginLeft:-L/2}).show();v=m||(H.currentStyle&&(H.currentStyle.position!="fixed"));if(v){H.style.position="absolute"}w(H).css("opacity",u.overlayOpacity).fadeIn(u.overlayFadeDuration);z();j(1);f=O;u.loop=u.loop&&(f.length>1);return b(N)};w.fn.slimbox=function(M,P,O){P=P||function(Q){return[Q.href,Q.title]};O=O||function(){return true};var N=this;return N.unbind("click").click(function(){var S=this,U=0,T,Q=0,R;T=w.grep(N,function(W,V){return O.call(S,W,V)});for(R=T.length;Q<R;++Q){if(T[Q]==S){U=Q}T[Q]=P(T[Q],Q)}return w.slimbox(T,U,M)})};function z(){var N=E.scrollLeft(),M=E.width();w([a,G]).css("left",N+(M/2));if(v){w(H).css({left:N,top:E.scrollTop(),width:M,height:E.height()})}}function j(M){if(M){w("object").add(m?"select":"embed").each(function(O,P){s[O]=[P,P.style.visibility];P.style.visibility="hidden"})}else{w.each(s,function(O,P){P[0].style.visibility=P[1]});s=[]}var N=M?"bind":"unbind";E[N]("scroll resize",z);w(document)[N]("keydown",o)}function o(O){var N=O.keyCode,M=w.inArray;return(M(N,u.closeKeys)>=0)?C():(M(N,u.nextKeys)>=0)?e():(M(N,u.previousKeys)>=0)?B():false}function B(){return b(x)}function e(){return b(D)}function b(M){if(M>=0){F=M;n=f[F][0];x=(F||(u.loop?f.length:0))-1;D=((F+1)%f.length)||(u.loop?0:-1);q();a.className="lbLoading";k=new Image();k.onload=i;k.src=n}return false}function i(){a.className="";w(g).css({backgroundImage:"url("+n+")",visibility:"hidden",display:""});w(p).width(k.width);w([p,I,d]).height(k.height);w(A).html(f[F][1]||"");w(K).html((((f.length>1)&&u.counterText)||"").replace(/{x}/,F+1).replace(/{y}/,f.length));if(x>=0){t.src=f[x][0]}if(D>=0){J.src=f[D][0]}L=g.offsetWidth;r=g.offsetHeight;var M=Math.max(0,y-(r/2));if(a.offsetHeight!=r){w(a).animate({height:r,top:M},u.resizeDuration,u.resizeEasing)}if(a.offsetWidth!=L){w(a).animate({width:L,marginLeft:-L/2},u.resizeDuration,u.resizeEasing)}w(a).queue(function(){w(G).css({width:L,top:M+r,marginLeft:-L/2,visibility:"hidden",display:""});w(g).css({display:"none",visibility:"",opacity:""}).fadeIn(u.imageFadeDuration,h)})}function h(){if(x>=0){w(I).show()}if(D>=0){w(d).show()}w(c).css("marginTop",-c.offsetHeight).animate({marginTop:0},u.captionAnimationDuration);G.style.visibility=""}function q(){k.onload=null;k.src=t.src=J.src=n;w([a,g,c]).stop(true);w([I,d,g,G]).hide()}function C(){if(F>=0){q();F=x=D=-1;w(a).hide();w(H).stop().fadeOut(u.overlayFadeDuration,j)}return false}})(jQuery);
Source: http://code.google.com/p/slimbox/issues/attachmentText?id=36&aid=360003000&name=slimbox2.js
Lightbox.prototype.build = function() {
var $lightbox,
_this = this;
$("<div>", {
id: 'lightboxOverlay'
}).appendTo('body');
$('<div/>', {
id: 'lightbox'
}).append($('<div/>', {
"class": 'lb-outerContainer'
}).append($('<div/>', {
"class": 'lb-container'
}).append($('<img/>', { ....
The problem you have can be easily solved. I've just spend an hour on it myself...
In the minified version of slimbox2, look for the following piece of code:
appendTo(G).append([w('<a id="lbCloseLink" href="#" />').add(H).click(C)[0]
Now replace that with the following:
appendTo(G).append([w('<a id="lbCloseLink" href="#" />').add(H).click(C).end()[0]
Some explanation:
Some divs are appended to the body, including lblOverlay (referenced by H in the compiled version). However, if you look at the piece above, by "add"-ing the H variable, it'll be appened to the lblContainer and won't be directly in the body ==> overlay jumps in front of the picture.
By adding "end()" to it, you'll only reference the "a"-element, instead of the "a"-element and the overlayer-element.
Tested in FF 20.0.1 and jQuery 1.9.1