lightbox2
lightbox2 copied to clipboard
Event listeners
I miss Event listeners when Lightbox is inicializated, when terminates or next/prev images are shown.
By example, I want to run a function to disable some keybindings when Lightbox is visible.
+1
Unfortunately lightbox does not provide that. But this would be helpful.
Why don't you add event listener on this awsome plugin? It would be grade if we can add some custom function to run during the lifetime of this plugin. For example, events will be fired whenever user click on an image, user move to another image...
+1
+1
+1
+1, and...
Though this would be on 3.0, I just want to share my version of patch to make it work with current implementation.
It tries to minimize code modification, and most of the code work is done outside the source. The only modification was to give access to the global Lightbox
instance.
Based on v2.7.4
-
Patch
lightbox.js
438c445 < var lightbox = new Lightbox(options); --- > var lightbox = Lightbox.lightbox = new Lightbox(options);
This just saves the instance under the global
Lightbox
object. -
Add a simple event system
var original = {}; function args(_arguments) { return Array.prototype.slice.apply(_arguments); } // add trigger/on Lightbox.prototype.trigger = function() { $(original).trigger.apply($(Lightbox.lightbox), args(arguments)); }; Lightbox.on = function() { $(original).on.apply($(Lightbox.lightbox), args(arguments)); };
With this now you can listen to events fired by Lightbox.
-
Decorate previous methods
original['init'] = Lightbox.prototype.init; Lightbox.prototype.init = function() { var result = original['init'].apply(this, arguments); var _args = args(arguments); _args.unshift(result); _args.unshift(this); this.trigger('onInit', _args); }; original['start'] = Lightbox.prototype.start; Lightbox.prototype.start = function() { var result = original['start'].apply(this, arguments); var _args = args(arguments); _args.unshift(result); _args.unshift(this); this.trigger('onStart', _args); }; original['end'] = Lightbox.prototype.end; Lightbox.prototype.end = function() { var result = original['end'].apply(this, arguments); var _args = args(arguments); _args.unshift(result); _args.unshift(this); this.trigger('onEnd', _args); }; original['changeImage'] = Lightbox.prototype.changeImage; Lightbox.prototype.changeImage = function() { var _args = args(arguments); _args.unshift(this); this.trigger('onBeforeChangeImage', _args); // var result = original['changeImage'].apply(this, arguments); // _args.unshift(result); this.trigger('onChangeImage', _args); }; original['showImage'] = Lightbox.prototype.showImage; Lightbox.prototype.showImage = function() { var result = original['showImage'].apply(this, arguments); var _args = args(arguments); _args.unshift(result); _args.unshift(this); this.trigger('onShowImage', _args); }; original['sizeContainer'] = Lightbox.prototype.sizeContainer; Lightbox.prototype.sizeContainer = function() { var result = original['sizeContainer'].apply(this, arguments); var _args = args(arguments); _args.unshift(result); _args.unshift(this); this.trigger('onSizeContainer', _args); };
Lots of code, but notice they all have the same structure. It just re-defines the original method, simply just triggering an event -- with the
trigger
method we just added at step 2 -- after each method call. Only exception is thechangeImage
method, where we have an additionalonBeforeChangeImage
method, which was required for my specific case. You are free to add your own.
Now here are some use cases of mine.
-
Disable body scroll while lightbox is on
Lightbox.on('onStart', function(event, result, self) { $('body').css('overflow-y', 'hidden'); }); Lightbox.on('onEnd', function(event, result, self) { $('body').css('overflow-y', ''); });
-
Render lightbox image in iframe
This is really a specific case. I need to fetch images from a server which checks the referrer and disables any request that is not from its own domain. One solution is to use iframe to destroy the referrer (see referrer-killer). To show the image inside the iframe, I swap the
img
after render:// show iframe image instead of window image Lightbox.on('onShowImage', function(event, result, self) { var $img = $('#lightbox img.lb-image'); // use iframe var $iframe = $img.next('iframe.iframify-lb-image'); var iimg = $iframe[0].contentWindow.document.getElementsByTagName('img')[0]; var $iimg = $(iimg); $iframe.attr({ 'width' : $img.css('width'), 'height': $img.css('height'), }); $iimg.attr('src', $img.attr('src')); $iimg.css({ 'width' : $img.css('width'), 'height': $img.css('height'), }); $iimg.fadeIn('slow'); // $img.stop(true).hide(); });
-
Preload images in iframe as well
Lightbox tries to "preload" the image and its neighboring images. To also move this into iframe, I temporarily "swap" the
Image
object between the window and the iframe during the request, and revert it back.// temporary patch window.Image to iframe.Image // to prevent preloader raising forbidden errors var originalWindowImage = null; Lightbox.on('onBeforeChangeImage', function(event, self) { var $_img = $('#lightbox img.lb-image'); var iframeWin = $_img.next('iframe.iframify-lb-image')[0].contentWindow; // patch window.Image originalWindowImage = window.Image; window.Image = iframeWin.Image; }); Lightbox.on('onShowImage', function(event, result, self) { window.Image = originalWindowImage; });
Hope this helps anyone.
jangxyz, have you updated your version to v2.8.2 aswell?