I have four buttons to show/hide slide card based on user selection. I show all products by default in total 10 cards. When changed to other options (the slide that only have four cards), there is a white space left. I tried to update with $productSlider.update() but it didn't work.
Demo Code (codesandbox)
Swiper Init
let $productSlider = new Swiper('.plan-slider-container', {
init: false,
observer: true,
observeParents: true,
observeSlideChildren: true,
spaceBetween: 0,
mousewheel: {
releaseOnEdges: true,
forceToAxis: true
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
keyboard: true,
scrollbar: {
el: '.swiper-scrollbar',
draggable: true,
hide: false,
},
breakpoints: {
320: {
slidesPerView: 1,
},
768: {
freeMode: true,
slidesPerView: 'auto'
}
}
});
User Selection Button
$('.choice-plan-btn-wrapper.desktop').on('click', e => {
let target = e.target;
let id = target.getAttribute('id');
let $parent = $(target).parent();
let lastActiveSiblingId = $(target).siblings('.active').attr('id');
if (target.tagName.toLowerCase() != 'button' || target.classList.contains('active')) return;
// button
$(target).addClass('active')
.siblings('.active').removeClass('active');
/* The Problem */
$parent.siblings('.plans-swiper-wrapper')
.children(`.${id}`).fadeIn('slow')
.siblings().not(`.${id}`).fadeOut('slow');
$productSlider.update();
/* The Problem */
$parent.siblings('.swiper-scrollbar')
.removeClass(`${lastActiveSiblingId}`)
.addClass(`${id}`)
$productSlider.slideTo(0, 500);
});
Related
I have an ACF + Gutenberg block that has a slider. There can be two such blocks on one page. How can I use two sliders with the same class on a page?
const selectedProductsSwiper = new Swiper(".product-swiper", {
centeredSlides: true,
speed: 1000,
slidesPerView: "auto",
modules: [Pagination, Controller, Navigation],
pagination: {
el: ".product-swiper__progressbar",
type: "progressbar",
},
navigation: {
nextEl: ".product-swiper__arrow-next",
prevEl: ".product-swiper__arrow-prev",
},
});
If I have multiple swiper.js sliders on a page then only the first slider works.
I used this slider as a guideline: https://swiperjs.com/demos#thumbs-gallery-loop
I have a lot of pages with multiple sliders, so a solution where you don't have to add classes or copy a lot of javascript would be good.
I think my JavaScript code is wrong.
I have found a solution how to run multiple sliders without thumbnail navigation on one page. The code: https://codepen.io/johannes-bichlmayr/pen/JjZVqqR
With thumbnail navigation it is very difficult. My current code: https://codepen.io/johannes-bichlmayr/pen/KKeYjgP
It does not work very well.
🔆This was my first JavaScript code that works very well with one slider per page:
var swiper = new Swiper(".mySwiper", {
loop: false,
spaceBetween: 10,
slidesPerView: document.getElementsByClassName('swiper-slide').length / 2,
freeMode: true,
watchSlidesProgress: true,
});
var swiper2 = new Swiper(".mySwiper2", {
loop: false,
spaceBetween: 10,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
thumbs: {
swiper: swiper,
},
});
🔆With the code you can run two sliders without thumbnail navigation on one page:
// declare Swiper.js .classes
const myCustomSlider = document.querySelectorAll('.swiper-container');
// declare navigation arrows classes
const mySliderPrev = document.querySelectorAll('.swiper-button-prev');
const mySliderNext = document.querySelectorAll('.swiper-button-next');
for( i=0; i< myCustomSlider.length; i++ ) {
// add special class with number to each Swiper.js slider and its nabigation arrows
myCustomSlider[i].classList.add('swiper-container-' + i);
mySliderPrev[i].classList.add('swiper-button-prev-' + i);
mySliderNext[i].classList.add('swiper-button-next-' + i);
var slider = new Swiper ('.swiper-container', {
effect: 'slide',
pagination: {
el: '.swiper-pagination',
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
scrollbar: {
el: '.swiper-scrollbar',
},
});
}
🔆I am working on the code right now:
// declare Swiper.js .classes
const myCustomSlider = document.querySelectorAll('.mySwiper2');
// declare navigation arrows classes
const mySliderPrev = document.querySelectorAll('.swiper-button-prev');
const mySliderNext = document.querySelectorAll('.swiper-button-next');
for( i=0; i< myCustomSlider.length; i++ ) {
// add special class with number to each Swiper.js slider and its nabigation arrows
myCustomSlider[i].classList.add('mySwiper2-' + i);
mySliderPrev[i].classList.add('swiper-button-prev-' + i);
mySliderNext[i].classList.add('swiper-button-next-' + i);
var swiper2 = new Swiper(".mySwiper2", {
loop: false,
spaceBetween: 10,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
thumbs: {
swiper: swiper,
},
});
}
// declare Swiper.js .classes
const myCustomSliderThumbs = document.querySelectorAll('.mySwiper');
for( i=0; i< myCustomSliderThumbs.length; i++ ) {
// add special class with number to each Swiper.js slider and its nabigation arrows
myCustomSliderThumbs[i].classList.add('mySwiper-' + i);
var swiper = new Swiper(".mySwiper", {
loop: false,
spaceBetween: 10,
slidesPerView: document.getElementsByClassName('swiper-slide').length / 2,
freeMode: true,
watchSlidesProgress: true,
});
}
Trying to make a simple carousel with an associated thumbs carousel under it:
// Thumbs
const galleryThumbs = new Swiper(thumbsElement, {
spaceBetween: 10,
slidesPerView: 4,
scrollbar: true,
breakpoints: {
768: {
slidesPerView: 8,
},
},
});
// Slides
const galleryTop = new Swiper(top, {
spaceBetween: 10,
effect: "fade",
loop: true,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
multipleActiveThumbs: false,
thumbs: {
swiper: galleryThumbs,
},
});
This is working as described, but I have a problem:
When one scrolls to the next image using the navigation arrows, and the corresponding thumbnail is out of sight, the thumbnails scroll in group(by the amount described in the slidesPerView setting). I'm looking for a way for it to scroll just by one, as it does when scrolling with the back arrow.
So I want to do this swiper.js carousel which slides linear from right to the left and after mouse hover it would stop. I used this function which works pretty fine:
$(".swiper-container3").hover(function() {
(this).swiper.autoplay.stop();
}, function() {
(this).swiper.autoplay.start();
});
If speed parameter is not defined in my swiper initialization function, then it stops after a hover (but only if the nearest slider will be on center of carousel).
How to force swiper.js to stop with the function above but not to wait for one of the sliders to be on center?
Rest of the code
const enableSwiper3 = function(){
mySwiper3 = new Swiper ('#swiper-container3', {
loop: true,
slidesPerView: "auto",
spaceBetween: 10,
centeredSlides: true,
a11y: true,
keyboardControl: true,
grabCursor: true,
freeMode: false,
pagination: {
el: '#swiper-pagination3',
},
paginationClickable: true,
breakpoints: {
400: {
slidesPerView: 'auto',
spaceBetween: 20,
loop: true
},
767: {
autoplay: {
delay: 5000,
disableOnInteraction: true,
pauseOnMouseEnter: true,
},
speed: 10000,
}
}
});
mySwiper3.autoplay.start();
}
I also want to lower its speed so whole slider goes linear very slow and just after hovering it it stops. Example on the site below: https://www.intercom.com/ (people are talking section).
How to stop swiper slide autoplay on mouse enter and start autoplay on mouse leave? I have tried .stopAutoplay() and .startAutoplay() function but not worked for me.
This is my output : click here
And here is the js code :
<script>
var slider = new Swiper ('#slider', {
slidesPerView: 1,
autoplay: 1000,
spaceBetween: 0,
loop: true,
loopedSlides: 6,
centeredSlides : true,
 disableOnInteraction: true,
autoplayDisableOnInteraction: false,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
slidesPerView: '1.3',
breakpoints: {
600: {
slidesPerView: 1
}
}
});
var thumbs = new Swiper('#thumbs', {
centeredSlides: true,
spaceBetween: 10,
loopedSlides: 6,
loop: true,
slidesPerView: "auto",
touchRatio: 0.2,
slideToClickedSlide: true,
breakpoints: {
600: {
slidesPerView: 3
}
}
});
slider.params.control = thumbs;
thumbs.params.control = slider;
$("#slider").mouseenter(function() {
slider.autoplay.stop();
});
$("#slider").mouseleave(function() {
slider.autoplay.start();
});
$("#thumbs").mouseenter(function() {
thumbs.autoplay.stop();
});
$("#thumbs").mouseleave(function() {
thumbs.autoplay.start();
});
</script>
Try to use $el element returned from instance. It works fine.
slider.$el.on('mouseover', () => {
slider.autoplay.stop();
});
slider.$el.on('mouseleave', () => {
slider.autoplay.start();
});
Check this example:
https://codepen.io/keitoliveira/pen/XWKdXMr