Each item of the gallery can have two interactions:

  • Link or activation: if image has a link or if options.activable is set to true
  • Lightbox zoom when gallery has option.lightbox set to true

If only one of those interactions is available, the whole image and/or button has the same hover effect and the same click action.

If both are available, hover and click is distinct between image and button.

Depending on the situation, the zoomable element may be different. That's why to customize the zoom effect you need bellow css selectors.

Public API

Property / Getter Type Description Docs
setItems(models[]) void Resets the collection and inits a new one
addItems(models[]) void Add items to current collection
addEventListener(name, callback, options) Subscribe to gallery events Docs
clear() void Empty the gallery and emits a pagination event
collectionLength number Size of full collection (including not yet displayed items)
domCollectionLength number Size of collection visible in the DOM
selectVisibleItems() void Select all items visible in the DOM
unselectAllItems() void Unselect all selected items
photoswipe object access to the PhotoSwipeLightbox object Docs


The gallery emits some events that allows you to implement rich interactions. You can listen to them as follow:

var elementRef = document.getElementById('gallery');

// The gallery accepts a literal as second argument for options
var gallery = new NaturalGallery.Natural(elementRef, options);

// Recommended: listen to gallery returned object
gallery.addEventListener(eventName, function(ev) {
    // Access to data provided by gallery in event by calling detail attribute
    var eventData = ev.detail;
}, {once: false, capture: false, passive: false});

Events summary

Event name Description Data format Docs
pagination Emitted when the gallery is ready to get the next items. Contains the limits of list for next items.
{offset: number, limit: number}
activate Emitted when an item has been clicked
{model: Object, clickEvent: MouseEvent}
select Emitted when an item is (un)selected. Contains the list of selected models
zoom Notifies the item and PhotoSwipe object when it's opened.
{item: Object, photoswipe: PhotoSwipeObject}
item-added-to-dom Emitted when the item has been added to DOM as empty rectangle, but image has not been lazy loaded yet
item-displayed Emitted when the image has lazy loaded and is visible


The gallery tells you what it needs !

It uses the options to estimate the number of items to display in the viewport and then notifies you.

This option is only useful if your gallery is binded with a server. The pagination events allows you to display a big collection by chunks. And it computes the chunks for you.

The event contains a start index and a number of items that are required by the gallery to work smoothly.

After each item is displayed into the DOM, the gallery asks an equivalent amount of items to add in the end of the collection. It behaves like a buffer to provide a fluid scrolling without interruptions due to server loading next query.

This cause the following scenario:

  1. The gallery init and uses configuration to estimate the number of items to display. For example: 3 rows can be visible, and it estimates a total of 20 items.
  2. The gallery emits a pagination event {offset: 0, limit: 20}
  3. When received, the items are added to the DOM, but due to the variable nature of image formats (for Natural and Masonry), all items may not be added. Those who are not go to a buffer.
  4. To fill the 3 rows the gallery add 15 items to the dom and then emits a new pagination event {offset: 20, limit: 15}.
  5. Those new 15 items are not added to DOM because user has not scrolled yet. They all go to the buffer and the gallery don't emits any new pagination event.
  6. The user scrolls slowly, 5 new items are added to next row. The gallery will emit a pagination event with {offset:35, limit: 5} and so on.

If the user scrolls faster, the pagination event is debounced to prevent you to spam your server. After a short inactivity (500ms) a new pagination event is emitted. It groups the offset and limits that would be produced by multiple notifications.

Due to the variable ratios of items in Natural and Masonry formats, the pagination is only an estimation. Each row can have a different number of images. For that reason the builtin pagination event is not compatible with a pagination of type PageSize and PageIndex.

gallery.addEventListener('pagination', function(ev) {
    console.log(ev.detail); // {offset: 0, limit: 23}


Emits when an item has been clicked for something else than opening the lightbox.

If the lightbox option is set to true, there are two scenarios where the activate event is emitted :

  • If items have a link, a button appears in place of the "raw" label. Clicking on the button emits an activate event.
  • If items don't have a link, but the gallery option.activable is set to true, the label becomes a button and a click on it emits an activate event.

If the lightbox option is set to false, these two scenarios stay valid, but the whole image area is considered as the button and emits the activate event.

gallery.addEventListener('activate', function(ev) {
    console.log(ev.detail); // {model: Object, clickEvent: MouseEvent}

    // Prevents to redirect to destination page in case clicked element is an <a href />


Emits a notification with an array that contains the list of the currently selected items.

Items in the list are the same as those provided as input.

gallery.addEventListener('select', function(ev) {
    console.log(ev.detail); // [Model1, Model2, Model3]


Emits a notification with the target item and PhotoSwipe object when the lightbox is opened after a click.

See more about PhotoSwipe API.

gallery.addEventListener('zoom', function(ev) {
    console.log(ev.detail); // {item: Object, photoswipe: PhotoSwipeObject}


An object that specifies characteristics about the event listener

See vanilla documentation

Test events by yourself

Open your console and click everywhere !

Bellow there are 4 differently configured galleries, with one item each. That's why :

  • Select event only contains a single item
  • Only the first pagination event from the first gallery is emitted. If you want to test pagination in infinite scroll condition, check the full collections pages.