Show a dynamic Swiper carousel upon selecting a thumbnail in an image gallery

I am in the process of creating a thumbnail gallery that includes a slider feature using Swiper. The default setup has the slider hidden, and once an image is clicked, the slider should appear with the selected image. To close the slider and return to the thumbnail gallery, users can click on a Close button.

Below is the code I have implemented:

Javascript:

var swiper;

swiper = new Swiper( '.gallery-slider .swiper-container', {
    loop: true,
    autoplay: {
        delay: 3000,
        disableOnInteraction: false,
    },
    navigation: {
        nextEl: '.swiper-next',
        prevEl: '.swiper-prev',
    },
});

$( '.gallery-thumbnails a[data-slide]' ).on( 'click', function( e ) {
    e.preventDefault();
    $( '.gallery-thumbnails' ).hide();
    $( '.gallery-slider' ).show();
    var slideno = $( this ).data( 'slide' );
    swiper.slideTo( slideno + 1, false, false );
});

$( '.gallery-slider .close' ).on( 'click', function( e ) {
    e.preventDefault();
    $( '.gallery-slider' ).hide();
    $( '.gallery-thumbnails' ).show();
});

CSS:

.gallery-slider {
    display: none;
}

HTML:

<div class="gallery-thumbnails">
    <div class="gallery-image"><a href="" data-slide="0"><img src="thumb0.jpg" /></a></div>
    <div class="gallery-image"><a href="" data-slide="1"><img src="thumb1.jpg" /></a></div>
    <div class="gallery-image"><a href="" data-slide="2"><img src="thumb2.jpg" /></a></div>
    <div class="gallery-image"><a href="" data-slide="3"><img src="thumb3.jpg" /></a></div>
    ....
</div>

<div class="gallery-slider">
    <div class="swiper-container">
        <div class="swiper-prev">previous</div>
        <div class="swiper-next">next</div>
        <div class="close">close</div>
        <div class="swiper-wrapper">
            <div class="swiper-slide"><img src="slide0.jpg" /></div>
            <div class="swiper-slide"><img src="slide1.jpg" /></div>
            <div class="swiper-slide"><img src="slide2.jpg" /></div>
            <div class="swiper-slide"><img src="slide3.jpg" /></div>
            ....
        </div>
    </div>
</div>

Although the slider appears when a thumbnail is clicked, it seems the functionality of the next and previous buttons within the slider is not working. Is it possible that the slider needs to be initialized when visible?

If you have any suggestions or insights on what might be incorrect, I would greatly appreciate your help

Thank you

Answer №1

It seems that including the observer and observeParents parameters in the Swiper initialization is crucial. This ensures that the slider gets updated (reinitialized) whenever there are changes made to its style (such as hide/show), modifications to its child elements (like adding/removing slides), or adjustments to its parent element.

let swiperInstance;

swiperInstance = new Swiper('.gallery-slider .swiper-container', {
    loop: true,
    observer: true,
    observeParents: true,
    autoplay: {
        delay: 3000,
        disableOnInteraction: false,
    },
    navigation: {
        nextEl: '.swiper-next',
        prevEl: '.swiper-prev',
    },
});

Answer №2

Implementing this feature involves utilizing a lightbox (fancybox) in conjunction with swiper. When a user clicks on a thumbnail, it triggers the opening of a lightbox displaying the selected item.

To begin, declare a variable for swiper and initialize it after the popup is loaded.

 var mySwiper = new Swiper('.gallery-slider', {
            init: false,
            slidesPerView: 1,
            centeredSlides: true,
            loop: false,
            observer: true,
            observeParents: true,
            
        });

Next, trigger the popup using fancybox.

$('#product-images-slider .elem').click(function(e) {
            e.preventDefault();
             
            var thisTargetImage = $('#product-images-slider .elem.image').index(this);

             
            $.fancybox.open({
                src: "#productLightbox",
                type: 'inline',
                opts: {
                    toolbar: false,
                    defaultType: 'inline',
                    autoFocus: true,
                    touch: false,
                     
                    afterLoad: function() {

                        mySwiper.init();
                        

                        // target to index image slide
                        mySwiper.slideTo(thisTargetImage);
                        
                    },
                      
                }
            })
        });

HTML code snippet for triggering the popup

 <div id="product-images-slider" class="prod-img-pic-wrap">
    <a class="elem fancybox-trigger image" data-type='image' href="..805fd8a03c0b67d44c8114c0087c030e-hi.jpg">
        <img src="..805fd8a03c0b67d44c8114c0087c030e-md.jpg" width="320">
    </a>
    </div>

Wrapper for the Swiper popup with fancybox integration

 <div id="productLightbox" class="gallery">
   
           <div class="swiper-container gallery-slider">
                <div class="swiper-wrapper"></div>
                <div class="swiper-button-next swiper-button-black"></div>
                <div class="swiper-button-prev swiper-button-black"></div>
            </div>
    </div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for switching the background image in React while a page is loading?

Is there a way to automatically change the background of a page when it loads, instead of requiring a button click? import img1 from '../images/img1.jpg'; import img2 from '../images/img2.jpg'; import img3 from '../images/img3.jpg& ...

JavaScript code for sending information to the server

I am attempting to write data to a file on the server when a user clicks on a button, using JavaScript. I followed the method outlined in this Stack Overflow post: Saving a text file on server using JavaScript. Unfortunately, it did not work as expected. ...

Hiding a Component: Achieving Smooth Behavior with Timer and onPress

My goal is to create a user interface where tapping the screen displays a <TouchableWithoutFeedback> component, which should automatically disappear after 4 seconds. Additionally, I want the user to be able to tap on the displayed component to hide ...

getting data from JavaScript function by making an asynchronous request to RESTful API

My current challenge involves calling a JavaScript method that utilizes AJAX to access a REST service and then return the response to the original call. While this may seem straightforward, I have scoured Stack Overflow for answers but haven't found a ...

The table remains visible during an AJAX call

I need assistance with removing a table after successful deletion triggered by an AJAX to PHP call. Below is the function provided: list.php <script type="text/javascript"> function massDelete() { if (!confirm("Are you sure")) ...

The steps to display a partial view within another view in React Native

Attempting to show the View after calling alert("Hi") in the renderMoreView function has been challenging for me. The alert works fine, but displaying the View is where I am encountering issues. class Main extends Component { state = { moreButton: f ...

CSS creates gaps between each of the internal elements inside the HTML document

I'm looking to create a 4px space between all internal components within my HTML, regardless of direction (top, bottom, left, or right). I have attempted to achieve this by using an external CSS file with the following code: body { padding: 2p ...

Having trouble getting the form to submit using AJAX

=====ANOTHER UPDATE==== (if anyone is interested!) The previous solution I shared suddenly stopped working for some reason. I added a beforeSend function to my ajax request and inserted the section of my JavaScript code that validates my form into it. It&a ...

Navigating through the concept of passing objects by reference in child components of Angular 2+

Understanding that TypeScript uses object passing by reference can be challenging, especially when dealing with deep copy issues. This becomes particularly cumbersome when working within a theme. I recently encountered an issue with a component containing ...

Trapping an anchor tag event in asp.net

I am currently working on a menu bar using HTML code (I am unable to use asp link buttons). <ul> <li><a href="#"><span>Reconciliation</span></a> <ul> ...

Tips for determining what elements are being updated in terms of style

I need assistance with modifying the functionality of a webpage's dropdown menu. Currently, it displays when the mouse hovers over it, but I want to change it to appear on click using my own JavaScript. Despite setting the onmouseout and onmouseover e ...

The jquery datepicker is malfunctioning after switching to another component

My current setup includes the following versions: jQuery: 3.3.1 jQuery UI: 1.12.1 AngularJS: 6 Here's a snippet of my code: <input id="test" type="text" class="form-control" value=""> In my component (component.t ...

Struggling to display the preloader animation while waiting for the render.com server to start up (using the free tier web service)

My choice for deploying dynamic websites is render.com and I am currently using their free tier. The issue with this free service is that Render spins down the web service after 15 minutes of inactivity, resulting in a delay when it needs to spin back up u ...

ngSwitchCase provider not found

While following a tutorial and trying to implement what I learned, I encountered an error that I'm having trouble understanding. The browser console shows an error message stating [ERROR ->]<span *ngSwitchCase="true">, but I can't figure ...

Conflicting styles arise when using the makeStyles function from Material UI with imported

In working on a React component library using create-react-library, I have incorporated basic components that utilize Material UI components and the material UI hook-based styles pattern. For example (in a simplified form): // LibraryComponent.js const u ...

What is the process of converting a byte array into a blob using JavaScript specifically for Angular?

When I receive an excel file from the backend as a byte array, my goal is to convert it into a blob and then save it as a file. Below is the code snippet that demonstrates how I achieve this: this.getFile().subscribe((response) => { const byteArra ...

The Selenium driver's execute_script() function is not functioning as expected

When I attempt to execute a JavaScript using driver.execute_script, nothing happens and the system just moves on to the next line of Python code. Any ideas? I've been web scraping on a webpage, using JavaScript in the Console to extract data. The Jav ...

Achieving 100% height in a div container using flex while maintaining vertical centering

Struggling to center text and buttons using flexbox while keeping the columns equal? Setting column height as 100% can be a challenge. If you set the height to 100%, vertical alignment may no longer be centered. Avoid resorting to tables or JavaScript for ...

user1234: I'm interested in decreasing the amount of items shown on the screen when it's smaller

Currently working on the design of the Search page for an online store. I aim to adjust the number of items displayed on the screen gradually as the screen size changes, similar to Amazon's layout. Additionally, I'm looking to rectify the excess ...

The identifier is not being used for the HTML element on the mobile browser

Having some issues with CSS priority on my mobile device. The problem is that the CSS id selector push-content is not being applied to the body element. Surprisingly, it works perfectly fine on my PC browser. The code that's not working on mobile dev ...