iDangero.us Swiper loop bug with previous navigation - javascript

When moving back through the loop using the "previous" navigation button the slides seem to jump from last to first. Issue seems to happen on all platforms.
Moving forward using navigation works as expected, and dragging works as expected.
I have done a fiddle based off the "Centered Slides + Auto Slides Per View" demo on the Swiper website, adding only the navigation html
<!-- Add Arrows -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
and the options
loop: true,
loopedSlides: 10,
roundLengths: true,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
JSFiddle here: https://jsfiddle.net/MatraSimca/L063jo3x/17/
In the production site I'm working on I'm using fixed width slides and the issue only seems to occur when adding
roundLengths: true,
With the percentage based widths in the demo fiddle the issue occurs with or without the roundLengths option. Any pointers appreciated...

loop functionality is duplicating only DOM nodes, meaning that your duplicated slides for the loop don't have their JS code appended as well, only the rendered result.
I spent 2 days trying to figure this out, so by using the original Swiper's methods and events, I came to a semi-infinite-loop feature:
add the following to your swiper's config
loop: true,
loopedSlides: 1,
on: {
slideChange: function () {
let lastVisibleItem = this.realIndex + this.params.slidesPerView
let slidesLength = this.slides.length - 2
let lastVisibleIndex = this.realIndex + this.params.slidesPerView
// if swiper reaches the end of displayed items, goToNext redirects swiper to the start
if (lastVisibleItem > slidesLength) {
this.slideTo(1)
}
// if swiper wants to go before the first item, then forward swiper to the last item
if (lastVisibleIndex >= this.slides.length) {
this.slideTo((slidesLength - this.params.slidesPerView) + 1)
}
}
}

Related

Swiper and current page index

I'm using Swiper API to let the user swipe across multiple pages on my HTML5/JS/CSS website.
I initialized the swiper (plase note I'm using Framework7 which includes Swiper API as an internal module, the app object represent the Framework7 instance:
var swiper = app.swiper.create('#swiper', {
speed: 200,
spaceBetween: 0,
initialSlide: 0,
loop: true,
pagination: {
el: '.swiper-pagination',
type: 'bullets',
},
autoHeight: true,
});
I also have three slides on my HTML:
<div class="swiper-container" id="swiper">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
<div class="swiper-pagination"></div>
</div>
I wrote a listener to listen for page changes: each time the user swipes to the next page, the transitionEnd event is fired
swiper.on("transitionEnd", function(e){
var slideIndex = swiper.activeIndex;
console.log("I'm on slide no: "+slideIndex);
});
When I try to retrieve the current slide index (swiper.activeIndex) I get very weird results: I would expect to get a number, either 0, 1 or 2 (the current page index).
If I don't wrap around I get 1,2,3 (ok, not 0-based, perfectly fine I'll add a -1). If I wrap around (Swiper seamlessly swipes in loop, wrapping around the pages) I also get 0, and 4 as indexes and I don't know why.
The documentation says that in loop mode (loop: true) the active page index works as follow:
Index number of currently active slide
Note, that in loop mode active index value will be always shifted on a
number of looped/duplicated slides
Still don't understand that sentence. "shifted on a number of looped slides"?
Inspecting the HTML I can see that Swiper API creates extra "duplicates" slides at the far left and right of the "real" slide sequence, to create the effect of a seamless loop across pages.
But if effectively I just have 3 pages, why I also get indexes 0 and 4 instead of just 1,2,3? (page1 = 1, page2 = 2, page3 = 3)?
With loop enabled, swiper duplicates the first slide to the end, and the last Slide before the first too keep the animation in flow.
3 Pages + 2 Duplicates = 5 Pages (index 0-4)
With swiper.activeIndex you are accessing the virtual slides, just use swiper.realIndex for the real index.

Swiper slideTo last slide, whilst snapping to left hand side

In Swiper demos, slides snap to the left of the screen until you get to the final slides, which are prevented from snapping to left because (I presume) Swiper doesn't want to show whitespace down the righthand side:
Slide 10 will never snap to the left side
https://swiperjs.com/demos/120-slides-per-view-auto.html
In my opinion it feels like a bug to the user, especially when you trigger slide to slide 10 and it only pops into the right side.
The workarounds I've found are to either add a blank slide, or to add margin-right to the final slide, so then slide will snap to the left side:
.swiper-slide:last-child {
margin-right: calc(100vw - 300px);
}
Add margin-right to last slide
https://codepen.io/kmturley/pen/ExxrGgw
Add blank slide at end
https://codepen.io/kmturley/pen/JjjzKrK
Use loop functionality and then hide duplicates
https://codepen.io/kmturley/pen/oNNVLxL
Is there a better or built-in way to do? this without having to use a workaround?
I want to change this spacing dynamically later and if you change it manually, then you have to call swiper.update() causing layout updates. Also my current workaround requires you to know the width of the slides, or use custom javascript to calculate the widths. So a built-in or responsive solution would be preferable!
try to add loopedSlides: 8, and remove margin-right: calc(100vw - 300px);
var container = document.getElementById('container');
var content = document.getElementById('content');
var swiper = new Swiper('.swiper-container', {
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
slidesPerView: 'auto',
autoplayDisableOnInteraction: false,
loopedSlides: 8,
});
Your current workaround probably is quite optimal and I don't htink there is any built in way to acheave what you are trying to do. However you could consider to use loop: true option and this could give a better user experience.
https://codepen.io/rentodesign/pen/gOOqNwo

Is there any way to make Swiper slide move with delay time vertically?

I'm trying to make a slide with Swiper.js and I'm trying to put some animation when I click the navigation button. So when I click the navigation button, some animation applies to the current slide and after the animation finish, I want it to move to the next or prev slide.
I've looked up Swiper API but I couldn't find the answer there and Since the slide should move vertically, it seems ever more difficult to implement this. Are there any ways to make Swiper Slide work like this?
Many thanks in advance.
To move the slider vertically you can specify direction: "vertical" in swiper init options.
var mySwiper = new Swiper ('.swiper-container', {
// Optional parameters
direction: 'vertical',
loop: true,
// If we need pagination
pagination: {
el: '.swiper-pagination',
},
// Navigation arrows
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// And if we need scrollbar
scrollbar: {
el: '.swiper-scrollbar',
},
})
To create custom transitions the below link might help.
https://medium.com/#arnost/creating-custom-slide-transitions-in-swiper-js-also-with-gsap-ac71f9badf53

Swiper and FullpageJS scrolling

I've got a little problem with those two. I'm using FullpageJS for my whole page scrolling and Swiper in one section.
My page contains 3 sections:
Intro section with some text and main menu
Products section where I've put Swiper
3.End section with contact form and footer.
FullpageJS is ofc scrolling only between these.
There's my swiper code:
let mySwiper = new Swiper('.swiper-container', {
// Optional parameters
releaseOnEdges: true,
direction: 'vertical',
loop:false,
centeredSlides: true,
breakpoints:{
768:{
direction:'horizontal',
slidesPerView: '1.1'
}
},
slidesPerView: '1.65',
mousewheel: {
invert: false,
releaseOnEdges:true,
}
});
As you can see swiper is controlled by mouse scroll.
There's my fullpageJS code:
$('#fullpage').fullpage({
controlArrows: false,
normalScrollElements: '#products',
});
"normalScrollElements" prevents fullpageJS from scrolling when #products section is on screen.
The problem that I'm facing is Swiper method 'isEnd' executes too fast. Products section contains full width and full height Swiper container with 10 slides.
What I want to do is to tell Swiper to slide to next section when I use mouse wheel after last slide. 'isEnd' method is working but not as I would like to.
It's scrolling page down in the same time when slide 9 is changing to slide 10 so I actually cant see what's there. I need to scroll back from section 3 to section 2 to see it. I want to call $.fn.fullpage.moveSectionDown();
ONLY when I try to scroll after slide 10.
All I had to do was to use "reachEnd".
on:{
reachEnd: function () {
setTimeout(function () {
$.fn.fullpage.setAllowScrolling(true);
},100)
}
}
After adding 'setTimeout', page doesn't scroll between slides 9 and 10 anymore :)

Swiper ( height issue – multiple swiper – vertical direction )

I would like to ash here a question, which I asking already in the developers forum of swiper, too. So don't be confused. If a solution is/was found, I will close/mark both.
At the moment I want for a project a horizontal scrolling sidebar and a vertical scrolling footer. (Swiper based)
But see self what happens if you switch from horizontal (1) footer to a vertical (2) one.
Video 1 (direction both horizontal - not wanted)
Video 2 (footer direction vertical, wanted! - not works)
As you can see, on the simplified example (Video 2):
If I use direction:vertical on the second swiper-container it breaks the result. Where the HEIGHT of "swiper-slide" should be 226px, appears now a HEIGHT of 2408px and a MARGIN-BOTTOM of 100px.
I really can't understand what's going wrong here.
ConfInit
var swiper = [];
$('.swiper-container').each(function(index){
var $el = $(this);
var sParams = [{
speed: 400,
spaceBetween: 100,
allowSwipeToNext: false, // for event controlled swipes
allowSwipeToPrev: false // for event controlled swipes
},
{
speed: 400,
spaceBetween: 100,
allowSwipeToNext: false, // for event controlled swipes
allowSwipeToPrev: false, // for event controlled swipes
direction: 'vertical'
}
];
I have faced the same issue, solved by adding height: 100vh declaration to swiper container.
Finding
height property is must
NOTE: % does not work

Categories