Reputation: 2019
I am applying the idangerous swiper scrollbar plugin on a container whose content is dynamically loaded with ajax, I initialize the plugin after the ajax call, the issue is that the scroll doesn't work until I resize the browser. I have tested it with static content it's working fine, no need to resize the window but once I switch to dynamic content, the scroll won't work unit I resize the browser.
Here's how am initializing the plugin
var mySwiper = new Swiper('.swiper-container', {
scrollContainer: true,
mousewheelControl: true,
mode: 'vertical',
scrollbar: {
container: '.swiper-scrollbar',
hide: true,
draggable: false
}
});
here's the html
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="searchList">
//here's the dynamic content being loaded (a list of div elements)
</div>
</div>
</div>
<div class="swiper-scrollbar">
</div>
</div>
swiper-container height is 100%
Upvotes: 21
Views: 59152
Reputation: 1201
I was running into the same issue and I tried several of the solutions i do have access to the swipper instance i used "update()" but it didn't work on my use case i haven't tried the "observer: true" config but i ended using a different approach before initializing the presentatational component that i have i add on the father component an "ng-container" tag to validate that the component doe snot render until the info it's available something like this:
<ng-container *ngIf="data?.items" >
<carousel-component [items]="data?.items"></table-component>
</ng-container>
In this way i ensure that i am going to init the component once i am completely sure the data it's available then i render the component on this way you don't run with the issue of the dinamic content don't being recognized by the carousel,.
Although this approach works in my use case because i just load the info one single time, i suggest if your case it's to change the images on a certain time lapse to use the "observer: true" option, it might sounds obvious my solution but there are a lot of beginners on angular that are not aware of this kind of solution, hope it helps someone like it did for me!.
Upvotes: 0
Reputation: 380
If you have images that change dynamically in your swiperjs slides, use observer: true
in the config object.
this.config = {
zoom: false,
slidesPerView: slidesPerView,
initialSlide: 12,
centeredSlides: true,
spaceBetween: 8,
scrollbar: false,
navigation: false,
pagination: false,
watchOverflow: true,
mousewheel: true,
observer: true, // <--------------------------add this
};
According to the documentation:
observer: true
- Set to true to enable Mutation Observer on Swiper and its elements. In this case Swiper will be updated (reinitialized) each time if you change its style (like hide/show) or modify its child elements (like adding/removing slides)
https://swiperjs.com/api/
Upvotes: 0
Reputation: 1
HTML
<div class="swiper-container">
<div class="swiper-wrapper" style="height: auto">
<div class="swiper-slide"><img src="" width="100%"></div>
<div class="swiper-slide"><img src="" width="100%"></div>
<div class="swiper-slide"><img src="" width="100%"></div>
<div class="swiper-slide"><img src="" width="100%"></div>
<div class="swiper-slide"><img src="" width="100%"></div>
</div>
<div class="swiper-pagination"></div>
</div>
CSS
.swiper-container {
width: 100%;
}
.swiper-slide {
text-align: center;
font-size: 18px;
background: #fff;
/* Center slide text vertically */
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
.swiper-pagination-bullet {
width: 10px;
height: 10px;
text-align: center;
line-height: 10px;
font-size: 12px;
color:#000;
opacity: 1;
background: rgba(255, 255, 255, 0.2);
}
.swiper-pagination-bullet-active {
color:#fff;
background: #000000;
}
javascript
var swiper = new Swiper('.swiper-container', {
pagination: '.swiper-pagination',
paginationClickable: true,
slidesPerView: 1,
spaceBetween: 0,
centeredSlides: true,
autoplay: 2500,
autoplayDisableOnInteraction: false,
loop: true,
autoHeight: true
});
Upvotes: 0
Reputation: 1401
Updated for Change in Swiper documentation since .reInit is no longer a function.
function reinitSwiper(swiper) {
setTimeout(function () {
swiper.update();
}, 500);
}
Upvotes: 8
Reputation: 2549
I just wanted to add that I also had trouble getting Swiper to work with dynamically loaded content through ajax
. This is quite obviously because the content wasn't loaded yet when Swiper was intiated. I solved this by using swiper's own appending function instead of my own. This was on version 3.3.1, and it fixed it for me without needing to use setTimeout()
or anything!
//quick and dirty creation of html to append
var imgHTML = "";
$.each(imgArray, function (i, url) {
imgHTML += '<div class="swiper-slide"><img src="' + url + '" alt=""/></div>';
});
//initiate swiper
var mySwiper = new Swiper('.swiper-container', {
// Optional parameters
loop: true,
autoHeight: true
});
mySwiper.appendSlide(imgHTML); //append the images
mySwiper.update(); //update swiper so it redoes the bindings
});
I hope this helps some people in need!
Upvotes: 2
Reputation: 6601
My fix for Swiper 3.x (I believe the above covers 2.x)
function fixSwiperForIE(swiper) {
setTimeout(function () {
swiper.onResize();
});
}
Upvotes: 6
Reputation: 51
I've got a no-JS solution.
HTML
<div class="responsive-swiper-holder">
<div class="responsive-swiper-shiv"></div>
<div class="swiper-container">
<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><!-- .swiper-container -->
</div><!-- .responsive-swiper-holder -->
CSS
.responsive-swiper-holder {
position: relative;
}
.responsive-swiper-shiv {
padding-top: 31.25%;
}
.swiper-container {
position: absolute;
height: 100%;
width: 100%;
top: 0;
}
.swiper-wrapper, .swiper-slide {
height: 100%;
}
Consequently this method will also work for making any div size responsively the way an image would. Scaling it's height with a locked aspect ratio of it's width.
The magic is that browsers treat margin/padding % values as a percentage of the width of the element even if you are padding the top or bottom of said element.
Hope this helps!
Upvotes: 5
Reputation: 282
For responsive design i call the following method resizeFix
function reinitSwiper(swiper) {
swiper.resizeFix(true)
}
Upvotes: -1
Reputation: 2019
I found the solution, I added this function which I call after first initializing the plugin
function reinitSwiper(swiper) {
setTimeout(function () {
swiper.reInit();
}, 500);
}
This fix was mentioned in another plugin and when I tried it with this swiper plugin it worked. It has something to do with the plugin not aware of the change that occurred to the DOM.
Upvotes: 15