19
votes

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%

9
not working with thumbs. please help me. this is my quesiton: stackoverflow.com/questions/57023310/…doğukan

9 Answers

15
votes

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.

6
votes

My fix for Swiper 3.x (I believe the above covers 2.x)

function fixSwiperForIE(swiper) {
    setTimeout(function () {
        swiper.onResize();
    });
}
6
votes

Updated for Change in Swiper documentation since .reInit is no longer a function.

function reinitSwiper(swiper) {
  setTimeout(function () {
   swiper.update();
  }, 500);
}
5
votes

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!

2
votes

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!

0
votes

swiper 3.4.2

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
});
0
votes

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/

0
votes

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!.

-1
votes

For responsive design i call the following method resizeFix

    function reinitSwiper(swiper) {
       swiper.resizeFix(true)
    }