I'm using a Bootstrap theme and I wanted the image gallery on the theme's image display page to load via AJAX. Photos come as JSON with AJAX but I couldn't get them to show on the page.
The gallery related part of this theme from the original JS file:
var productGallery = function () {
var gallery = document.querySelectorAll('.product-gallery');
if (gallery.length) {
var _loop8 = function _loop8(i) {
var thumbnails = gallery[i].querySelectorAll('.product-gallery-thumblist-item'),
previews = gallery[i].querySelectorAll('.product-gallery-preview-item');
for (var n = 0; n < thumbnails.length; n++) {
thumbnails[n].addEventListener('click', changePreview);
} // Changer preview function
function changePreview(e) {
e.preventDefault();
for (var _i3 = 0; _i3 < thumbnails.length; _i3++) {
previews[_i3].classList.remove('active');
thumbnails[_i3].classList.remove('active');
}
this.classList.add('active');
gallery[i].querySelector(this.getAttribute('href')).classList.add('active');
}
};
for (var i = 0; i < gallery.length; i++) {
_loop8(i);
}
}
}();
Data from JSON file with Ajax:
some AJAX code..
if (slidePhotos.photos) {
for (let x= 0; x< slidePhotos.photos.length; x++) {
document.getElementById('gallery_photos_div').innerHTML += '<div class="product-gallery-preview-item" id="' + x+ '"><img src="' + slidePhotos.photos[x].url + '" alt=""></div>';
document.getElementById('gallery_thumbs_div').innerHTML += '<a class="product-gallery-thumblist-item" href="#' + x+ '"><img src="' + slidePhotos.photos[x].url + '"></a>';
}
}
The HTML Code is generated but unfortunately the images do not change when I click on it.
Sample JSON:
[
{
"url":"https://example.com/image1.jpg",
"url":"https://example.com/image2.jpg"
}
]
Can you tell me where I made a mistake?
I see a couple of problems here:
div.product-gallery-preview-item
to your slideshow container, but doesn't append a corresponding .product-gallery-thumblist-item
. In your productGallery
function, your click
handler is being bound to the latter, not the former. You'll want to make sure those target thumbnail elements are added as well as the preview ones.productGallery
function is fired when the page/DOM is first loaded to initialize the slideshow. The click
event handlers that control the functionality of your slideshow are bound only to the elements that are present when the function runs. If you're not running this function repeatedly when appending content via AJAX (I hope you're not, as this would bind duplicate event handlers to the elements already in the slideshow), you'll need to ensure that your new elements are primed to respond to click
in the same way that your existing ones are. You have a couple of options here:
productGallery
so that it can be invoked repeatedly with the same slideshow, e.g: adding a :not(.slideshow-processed)
to the the end of your .product-gallery-thumblist-item
and .product-gallery-preview-item
query selectors, and then adding the slideshow-processed
class to these elements after binding your event handlers so they won't be processed again during subsequent invocations of productGallery
.productGallery
to use event delegation (where a parent element listens for an event that occurs on one of its child elements). This would allow you to bind your event handler to the .product-gallery
container just once, and have it fire for any preview/thumbnail pair that gets appended to the slideshow, without having to re-invoke productGallery
. You can read more about event delegation at https://javascript.info/event-delegation.Hopefully this points you in the right direction. Happy coding!