Featured image of post How to Create a Swiper Grid Loop in jQuery

How to Create a Swiper Grid Loop in jQuery

Discover how to craft a responsive grid slider using jQuery and Swiper. Enhance your content display across devices with this step-by-step guide.

Have you ever wanted to showcase multiple pieces of content in a slider that not only adapts seamlessly to different screen sizes but also loops endlessly?

For instance, an online store might want to feature a product list, or a portfolio might aim to effectively showcase its work. In this post, we’ll dive into how to implement a responsive grid slider using jQuery and the Swiper library.


HTML Structure

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<div class="slider">
    <div class="viewport">
        <div class="swiper-wrapper">
            <div class="item">1</div>
            <div class="item">2</div>
            <div class="item">3</div>
            <div class="item">4</div>
            <div class="item">5</div>
            <div class="item">6</div>
            <div class="item">7</div>
            <div class="item">8</div>
            <div class="item">9</div>
            <div class="item">10</div>
            <div class="item">11</div>
            <div class="item">12</div>
        </div>
    </div>
    <div class="swiper-prev">Previous</div>
    <div class="swiper-next">Next</div>
    <div class="swiper-pagination"></div>
</div>
  • Basic Slider Structure
    The .slider class wraps the entire component, while the .viewport contains the actual sliding content. Inside the viewport, the .swiper-wrapper class is placed, which is recognized by the Swiper library.

  • Slide Items
    Each item in the slide uses the .item class. In this example, we’ve created 12 items, numbered 1 to 12.

  • Navigation and Pagination
    The .swiper-prev and .swiper-next are the slider navigation buttons, and the .swiper-pagination indicates the current slide position. These elements are automatically handled by the Swiper library.


CSS Styling

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
.slider { position: relative; max-width: 1180px; margin: 20px auto 0; padding: 0 50px; } 
.slider .viewport { overflow: hidden; } 
.slider .swiper-slide { display: grid; gap:10px; grid-template-columns: repeat(3, 2fr); } 
.slider .item { width: 100%; height: 150px; background: #8ab4f8; font-size: 20px; line-height: 150px; text-align: center; } 
.slider .swiper-prev, .slider .swiper-next { position: absolute; top: 50%; width: 35px; height: 35px; background:url('images/arrow.png') center center no-repeat; background-size: cover; font-size: 0; text-indent: -999em; cursor: pointer; } 
.slider .swiper-prev { left: 0; transform: rotateY(180deg) translate(0,-50%); } 
.slider .swiper-next { right:0; transform: translate(0,-50%); } 
.slider .swiper-pagination { display: flex; justify-content: center; position: relative; width: 100%; margin-top: 20px; } 
.slider .swiper-pagination-bullet { width: 10px; height: 10px; margin: 0 5px; background: #ccc; opacity: 1; } 
.slider .swiper-pagination-bullet-active { background: #8ab4f8; } 

@media (max-width: 767px){
    .slider .swiper-slide { grid-template-columns: repeat(3, 1fr); } 
}
  • Slider Layout
    The .slider is centered on the screen with a maximum width and margin settings. Padding is added to accommodate navigation buttons.

  • Grid Layout
    The .swiper-slide uses CSS grid to arrange 6 items in a 3x2 format within a slide. The gap property sets the spacing between items.

  • Item Styling
    Each .item has a fixed height and background color, with text centered.

  • Navigation Buttons
    The previous/next buttons are positioned absolutely on the sides of the slider. The previous button’s arrow image is rotated with rotateY to point in the opposite direction.

  • Pagination
    Pagination is centered using flex, with styles defined for each bullet and the active state.

  • Responsive Handling
    For mobile screens (767px and below), the grid column width is adjusted to ensure three items remain visible on narrower screens.


jQuery Code

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
function slideAct() {
    // Select slider elements
    const $sliders = $(".slider");
    
    // Responsive settings
    const config = {
        breakpoints: [
            { name: 'desktop', width: 768, itemsPerView: 6 },  // PC: 6 items per view
            { name: 'mobile', width: 0, itemsPerView: 3 }      // Mobile: 3 items per view
        ]
    };
    
    // Slider state management
    const state = {
        swipers: [],         // Swiper instances
        originalItems: [],   // Original items
        slideIndexes: [],    // Slide positions
        deviceMode: ''       // Current device mode
    };
    
    // Initialize sliders
    function initSliders() {
        $sliders.each(function(index) {
            state.slideIndexes[index] = 0;
            // Save original items
            if (!state.originalItems[index]) {
                state.originalItems[index] = $(this).find('.item').clone();
            }
        });
    }
    
    // Return current device mode
    function getDeviceMode(windowWidth) {
        const breakpoint = config.breakpoints.find(bp => windowWidth >= bp.width);
        return breakpoint ? breakpoint.name : config.breakpoints[config.breakpoints.length - 1].name;
    }
    
    // Reconfigure sliders on window resize
    $(window).on('resize', function() {
        const newDeviceMode = getDeviceMode(window.innerWidth);
        if (state.deviceMode !== newDeviceMode) {
            state.deviceMode = newDeviceMode;
            arrangeSlides();
        }
    });
    
    // Rearrange slides
    function arrangeSlides() {
        // Calculate number of items per view for current mode
        const breakpoint = config.breakpoints.find(bp => bp.name === state.deviceMode);
        const itemsPerView = breakpoint ? breakpoint.itemsPerView : config.breakpoints[0].itemsPerView;
        
        // Reset existing slides
        $sliders.find('.item').parent('.swiper-slide').each(function() {
            $(this).find('.item').unwrap();
        });
        $sliders.find('.swiper-slide-duplicate').remove();
        
        // Recreate slides
        $sliders.each(function(index) {
            const $currentSlider = $(this).addClass(`slider-${index}`);
            const $wrapper = $currentSlider.find('.swiper-wrapper');
            $wrapper.empty();
            
            // Clone original items and create slides
            const $items = state.originalItems[index].clone();
            const itemCount = $items.length;
            for (let i = 0; i < itemCount; i += itemsPerView) {
                const $slide = $('<div class="swiper-slide"></div>');
                $items.slice(i, i + itemsPerView).clone().appendTo($slide);
                $wrapper.append($slide);
            }
            // Initialize swiper after processing last slider
            if (index === $sliders.length - 1) {
                initSwipers(itemsPerView);
            }
        });
    }
    
    // Create Swiper instances
    function initSwipers(itemsPerView) {
        $sliders.each(function(index) {
            const $currentSlider = $(this);
            // Destroy existing swiper
            if (state.swipers[index]) {
                state.swipers[index].destroy(true, true);
                state.swipers[index] = null;
            }
            // Swiper configuration
            const swiperConfig = {
                slidesPerView: 1,
                initialSlide: Math.floor(state.slideIndexes[index] / itemsPerView),
                loop: true,
                navigation: {
                    nextEl: $currentSlider.find('.swiper-next')[0],
                    prevEl: $currentSlider.find('.swiper-prev')[0],
                },
                pagination: {
                    el: $currentSlider.find('.swiper-pagination')[0],
                    clickable: true,
                    renderBullet: function(index, className) {
                        return `<span class="${className}"></span>`;
                    }
                },
                on: {
                    slideChange: function() {
                        state.slideIndexes[index] = this.realIndex * itemsPerView;
                    }
                }
            };
            // Create swiper
            state.swipers[index] = new Swiper($currentSlider.find('.viewport')[0], swiperConfig);
        });
    }
    
    // Initialize and execute
    initSliders();
    state.deviceMode = getDeviceMode(window.innerWidth);
    arrangeSlides();
}

$(document).ready(function() {
    slideAct();
})
  • Configuration and State Management
    The config object defines responsive breakpoints, specifying how many items to display based on the screen size. The state object is used to track the current state of the slider.

  • Initialization Function
    The initSliders function clones and saves the original items for each slider. These original items are used to create new slides when the screen size changes.

  • Device Mode Detection
    The getDeviceMode function returns ‘desktop’ or ‘mobile’ mode based on the current window width. If the device mode changes during a resize event, the slides are reconfigured.

  • Rearranging Slides
    The arrangeSlides function reconfigures the slides to match the current device mode. It resets existing slides and groups the original items into new slides based on the current mode.

  • Creating Swiper Instances
    The initSwipers function creates and configures Swiper instances, utilizing features such as infinite looping, navigation, and pagination. The current slide index is saved in state when the slide changes.


Extending Responsive Settings: Adding Tablet

1
2
3
4
5
6
7
8
// Responsive settings (adding tablet)
const config = {
    breakpoints: [
        { name: 'desktop', width: 1024, itemsPerView: 6 },  // PC: 6 items per view (1024px and above)
        { name: 'tablet', width: 768, itemsPerView: 4 },    // Tablet: 4 items per view (768px to 1023px)
        { name: 'mobile', width: 0, itemsPerView: 3 }       // Mobile: 3 items per view (767px and below)
    ]
};

By adding a tablet setting to the breakpoints array, you can achieve more precise responsive control for different devices. Note that the width values should be sorted from largest to smallest, as the getDeviceMode function finds the first breakpoint where the window width meets or exceeds its width value.


Practical Tips

  • Supporting Multiple Sliders
    This code supports multiple sliders on a single page. Each slider’s state is independently stored in the state object’s array.

  • Various Grid Layouts
    You can implement various grid layouts by modifying the CSS grid-template-columns property. For example, you can change it to a 2x3 or 4x2 grid as needed.


Conclusion

In this post, we explored how to implement a responsive grid slider using jQuery and Swiper. This code automatically adjusts the content layout based on screen size while providing infinite looping and convenient navigation. It’s particularly useful for websites that need to display multiple pieces of content in a grid format.

Was this tutorial helpful? If you have any questions or suggestions, feel free to share them in the comments below. Let’s keep building better code together!


comments powered by Disqus
Hugo로 만듦
JimmyStack 테마 사용 중