Nested horizontal sliders with click controls - javascript

How do I get a nested horizontal slider to work with click controls by show/hiding them.
I'm using Swiper which I have almost working except if you click / transition into the nested slider, you can't go back from that first slide without first transition one slide. If you click all the way to the end and back, it works perfectly. There are many callbacks in the Swiper api available.
My progress so far: Nested slider Fiddle
$(document).ready(function() {
var swiperH = new Swiper('.swiper-container-h', {
pagination: '.swiper-pagination-h',
paginationClickable: true,
spaceBetween: 0,
nextButton: '.h-next',
prevButton: '.h-prev',
onSlideChangeStart: function() {
if ($('.swiper-container-h .swiper-slide-active').children().hasClass('swiper-container-v')) {
console.log('nested');
$('.h-prev, .h-next').hide();
} else {
console.log('notnested');
$('.h-prev, .h-next').show();
}
},
onReachBeginning: function() {},
onReachEnd: function() {}
});
var swiperV = new Swiper('.swiper-container-v', {
pagination: '.swiper-pagination-v',
paginationClickable: true,
direction: 'horizontal',
spaceBetween: 0,
nextButton: '.v-next',
prevButton: '.v-prev',
nested: true,
onReachBeginning: function() {
$('.h-prev').show();
},
onReachEnd: function() {
$('.h-next').show();
},
onSlideChangeStart: function(slides) {
if (slides.activeIndex === 1) {
console.log('slide 2');
}
}
});
});
EDIT:
Cleaned up fiddle using #TheOnlyError 's answer here and here:
$(document).ready(function() {
var swiperH = new Swiper('.swiper-container-h', {
pagination: '.swiper-pagination-h',
paginationClickable: true,
spaceBetween: 0,
nextButton: '.h-next',
prevButton: '.h-prev',
onSlideChangeStart: function() {
if ($('.swiper-container-h .swiper-slide-active').children().hasClass('swiper-container-v')) {
$('.h-prev, .h-next').hide();
} else {
$('.h-prev, .h-next').show();
}
},
onSlideNextStart: function() {
$('.h-prev').show();
}
});
var swiperV = new Swiper('.swiper-container-v', {
pagination: '.swiper-pagination-v',
paginationClickable: true,
direction: 'horizontal',
spaceBetween: 0,
nextButton: '.v-next',
prevButton: '.v-prev',
nested: true,
onReachBeginning: function() {
$('.h-prev').show();
},
onReachEnd: function() {
$('.h-next').show();
},
});
});
Edit2:
Just encountered that if the first slide is nested, this doesn't work. To solve this prob you will also need to add:
onInit: function(){
if ($('.swiper-container-h .swiper-slide-active').children().hasClass('swiper-container-h-inner')) {
$('.prev, .next').hide();
}
},
to the first slider: Fiddle

The problem is that Swiper won't detect the transition between seperate Swiper objects. The solution would be checking when one has swiped to the next slide from the first horizontal one, to show the previous button.
So add this function to your first Swiper object:
onSlideNextStart: function(swiper) {
$('.h-prev').show();
}
Check the fiddle.

Related

Swiper JS - Lazyload not working on duplicate slides for looping slide

I'm trying to use Swiper JS and its native lazy loading params but it's not working on duplicate or cloned slides. Here's an exemple :
var lazyLoadImages = new LazyLoad({
elements_selector: ".lazy",
});
const swiper3 = new Swiper('.swiper-container', {
loop: true,
slidePerView: 1,
lazy: true,
pagination: {
el: '.swiper-pagination',
clickable: true
},
navigation: {
nextEl: '.swiper-button-next-unique',
prevEl: '.swiper-button-prev-unique',
},
preloadImages: true
});
if (lazyLoadImages) {
lazyLoadImages.update();
}

Why doesn't the number of the active slide change in Swiper JS in pagination with a fraction?

I have an .image-slider__fraction block that I tried to set up to display the number of the active slide from the total number of slides, but for some reason in the javascript it gives me the error "Uncaught ReferenceError: myImageSLider is not defined", but I don't understand why
Site http://ilyin1ib.beget.tech/
Code https://jsfiddle.net/qav8z7f3/
let mySliderAllSlides = document.querySelector('.image-slider__total');
let mySliderCurrentSlide = document.querySelector('.image-slider__current');
mySliderAllSlides.innerHTML = myImageSLider.slides.length;
myImageSLider.on('slideChange', function() {
let currentSlide = ++myImageSLider.realIndex;
mySliderCurrentSlide.innerHTML = currentSlide;
});
<div class="image-slider__fraction">
<div class="image-slider__current">1</div>
<div class="image-slider__sepparator">/</div>
<div class="image-slider__total">1</div>
</div>
You can achieve it like this. https://jsfiddle.net/zoymLphf/
Use swiper API methods. Counting the total number of slides is kinda tricky when you use loop mode, maybe there is a more elegant solution for this.
const swiper = new Swiper('.image-slider', {
// Optional parameters
slidesPerView: 3,
on: {
init: function(sw) {
$('.image-slider__total').text($('.swiper-slide:not(.swiper-slide-duplicate)').length)
$('.image-slider__current').text(sw.realIndex + 1)
},
slideChange: function (sw) {
$('.image-slider__current').text(sw.realIndex + 1)
},
},
spaceBetween: 30,
direction: 'horizontal',
centeredSlides: true,
loop: true,
loopedSLides: 3,
simulateTouch: true,
grabCursor: true,
speed: 800,
pagination: {
el: '.swiper-pagination',
type: 'progressbar'
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
autoplay: {
delay: 1000,
}
});

Swiper slider do not work after infinite scroll load more information

I'm using Swiper slider for some images on homepage with infinite scroll to load more information on scrolling on Opencart platform.
The problem is coming when i scrolling down and more content is loaded with infinite scroll than Swiper Slider arrows are not working for the new content
I initialize Swiper in a footer to be sure will be initialize after home is loaded even i do it with loop but still same issue
Any ideas how I can sort out this issue ?
Swiper
$(".swiper-container").each(function(index, element) {
var swiper = new Swiper('.swiper-container', {
slidesPerView: 1,
loop: true,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
pagination: {
el: '.swiper-pagination'
},
spaceBetween: 10,
});
});
Infinite scroll
$("#listproduct").addClass("infinitescroll");
var $container = $('.infinitescroll');
$container.infinitescroll({
navSelector: ".pagination",
nextSelector: ".next-pagination",
itemSelector: ".product-layout",
history: 'push',
loading: {
msgText: "Loading ....",
}
},
UPDATE
I manage to make it work with next changes
Swiper
var options = {
slidesPerView: 1,
loop: true,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
pagination: {
el: '.swiper-pagination'
},
spaceBetween: 10,
},
swiper = new Swiper('.swiper-container', options);
Infinite
$("#listproduct").addClass("infinitescroll");
var $container = $('.infinitescroll');
$container.infinitescroll({
navSelector: ".pagination",
nextSelector: ".next-pagination",
itemSelector: ".product-layout",
history: 'push',
loading: {
msgText: "Loading ....",
}
},function(){
swiper = new Swiper('.swiper-container', options);
}
Swiper has an update method in its API:
swiper.update();
You'll need to run that in your infinite scroll load event callback. That might look like this:
$container.on( 'load.infiniteScroll', function() {
swiper.update();
});
Look like destroy is called somewhere in the infinite scroll and Swiper must be re-initialize once loading is finished this will work for v2 infinite
Swiper
var options = {
slidesPerView: 1,
loop: true,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
pagination: {
el: '.swiper-pagination'
},
spaceBetween: 10,
},
swiper = new Swiper('.swiper-container', options);
Infinite
$("#listproduct").addClass("infinitescroll");
var $container = $('.infinitescroll');
$container.infinitescroll({
navSelector: ".pagination",
nextSelector: ".next-pagination",
itemSelector: ".product-layout",
history: 'push',
loading: {
msgText: "Loading ....",
}
},function(){
swiper = new Swiper('.swiper-container', options);
}

Pause video on slide in slider.io

I'm building a video gallery using slider.io and I want that the video pauses if a user goes to next slide/video. I'm trying to use onSlideChangeStart and onSlideChangeEnd function however it is not working.
code:
var swiper = new Swiper('.swiper-container', {
pagination: '.swiper-pagination',
slidesPerView: 'auto',
centeredSlides: true,
paginationClickable: true,
spaceBetween: 0,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
loop: true,
onSlideChangeStart: function (swiper) {
$('.swiper-button-next').click(function () {
$('video')[0].pause();
});
},
onSlideChangeEnd: function (swiper) {
$('.swiper-button-next').click(function () {
$('video')[0].pause();
});
}
});
onSlideChangeStart and onSlideChangeEnd you can check if any video is playing in next or prev slide then pause it.
working fiddle
onSlideChangeStart: function(swiper) {
if ($('.swiper-slide-next video')[0]) $('.swiper-slide-next video')[0].pause();
if ($('.swiper-slide-prev video')[0]) $('.swiper-slide-prev video')[0].pause();
},
onSlideChangeEnd: function(swiper) {
if ($('.swiper-slide-next video')[0]) $('.swiper-slide-next video')[0].pause();
if ($('.swiper-slide-prev video')[0]) $('.swiper-slide-prev video')[0].pause();
},
I found a solution for this by using the below method
var swiper = new Swiper('.swiper-container', {
pagination: '.swiper-pagination',
slidesPerView: 'auto',
centeredSlides: true,
paginationClickable: true,
spaceBetween: 0,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
loop: true,
onSlideChangeStart: function (swiper) {
$('.swiper-slide').find('video').each(function() {
this.pause();
});
},
onSlideChangeEnd: function (swiper) {
$('.swiper-slide').find('video').each(function() {
this.pause();
});
}
});

How to make autoplay of the Swiper slider start only after the slider enters viewport?

I'm using this code to initialize swiper slider.
var mySwiper = new Swiper ('.swiper-container', {
// Optional parameters
pagination: '.swiper-pagination',
paginationClickable: true,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
spaceBetween: 0,
parallax: true,
autoplay: 5000,
speed: 800,
autoplayDisableOnInteraction: false
})
Since the slider is positioned inside the fourth section of the page and is visible only after the page is scrolled down, I would like to make the autoplay start only after the slider enters the viewport.
Is there a way to do this?
var mySwiper = new Swiper('.swiper-container', {
autoplay: {
delay: 5000,
},
});
Assuming you're trying play on 4th slides:
var mySwiper = new Swiper ('.swiper-container', {
// Optional parameters
pagination: '.swiper-pagination',
paginationClickable: true,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
spaceBetween: 0,
parallax: true,
autoplay: 5000,
speed: 800,
autoplayDisableOnInteraction: false,
onSlideChangeStart: function(s){
if (s.activeIndex === 3) {
// do something here, 4th slide is active now and so on
console.log('hi! Try to reach 4th slides');
s.startAutoplay(); // calling autoplay on 4th slides.
}
}
})
You could potentially use something like jquery appear - https://github.com/morr/jquery.appear
$('mySwiperContainer').on('appear', function(event, $all_appeared_elements) {
// this element is now inside browser viewport
var mySwiper = new Swiper ('.swiper-container', {
// Optional parameters
pagination: '.swiper-pagination',
paginationClickable: true,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
spaceBetween: 0,
parallax: true,
autoplay: 5000,
speed: 800,
autoplayDisableOnInteraction: false
})
});
Object with autoplay parameters needs to be used, or just boolean true to enable with default settings to enable autoplay. Here is an example with delay (between transitions in ms) parameter:
const swiper = new Swiper('.swiper', {
autoplay: {
delay: 5000,
},
});
Documentation reference here

Categories

Resources