Slick Slider zero width in hidden container (Bootstrap tab)

大憨熊 提交于 2019-12-18 09:08:07

问题


I'm using a Bootstrap 4 tab navigation to view different sliders inside the tab panels.

It works well for the active tab. But the sliders in the inactive tabs have an width of 0 (.slide-track). So there is a display problem until I'm start to navigate through the tabs. After that, the width is set and the slider looks fine.

Is there any way to set the width of the slide track to the correct size?

$('.slider-home').slick({
  dots: true,
  arrows: true,
});

$('.slider-profile').slick({
  dots: true,
  arrows: true,
});

$('.slider-contact').slick({
  dots: true,
  arrows: true,
});
.slick-prev:before,
.slick-next:before {
  color: blue;
}

.tab-pane {
  padding: 2rem 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="http://cdn.jsdelivr.net/jquery.slick/1.3.15/slick.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<link href="http://cdn.jsdelivr.net/jquery.slick/1.3.15/slick.css" rel="stylesheet" />
<link href="https://kenwheeler.github.io/slick/slick/slick-theme.css" rel="stylesheet" />

<div class="container">
  <ul class="nav nav-tabs" id="myTab" role="tablist">
    <li class="nav-item"><a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a></li>
    <li class="nav-item"><a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a></li>
    <li class="nav-item"><a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a></li>
  </ul>
  <div class="tab-content" id="myTabContent">
    <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
      <div class="slider-home">
        <div>
          <p class="h1">home 1</p>
        </div>
        <div>
          <p class="h1">home 2</p>
        </div>
        <div>
          <p class="h1">home 3</p>
        </div>
        <div>
          <p class="h1">home 4</p>
        </div>
      </div>
    </div>
    <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
      <div class="slider-profile">
        <div>
          <p class="h1">profile 1</p>
        </div>
        <div>
          <p class="h1">profile 2</p>
        </div>
        <div>
          <p class="h1">profile 3</p>
        </div>
        <div>
          <p class="h1">profile 4</p>
        </div>
        <div>
          <p class="h1">profile 5</p>
        </div>
      </div>
    </div>
    <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">
      <div class="slider-contact">
        <div>
          <p class="h1">contact 1</p>
        </div>
        <div>
          <p class="h1">contact 2</p>
        </div>
        <div>
          <p class="h1">contact 3</p>
        </div>
      </div>
    </div>
  </div>
</div>

View on JSFiddle


回答1:


The problem is because when a container is hidden it's not possible for its child elements to calculate their widths.

To get around this you could instead instantiate the slick() controls when the tabs are shown. Then the widths can be calculated. Try this:

$('a[data-toggle="tab"]').on('shown.bs.tab', function() {   
  $($(this).attr('href')).find('.slider').slick({
    dots: true,
    arrows: true
  })
}).first().trigger('shown.bs.tab');

Working example




回答2:


Another solution is to manually refresh the initialized slider after it's shown.
Here's a demonstration:

// Initialize sliders.
$('.slider').slick({
  dots: true,
  arrows: true,
});

// When a tab is shown...
$('.nav-link').on('shown.bs.tab', function() {

  // ... select the corresponding tab pane ...
  let $tabPane = $($(this).attr('href'));

  // ... and refresh its slider.
  $('.slider', $tabPane).slick('refresh');

});
.slick-prev:before,
.slick-next:before {
  color: blue;
}

.tab-pane {
  padding: 2rem 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script type="text/javascript" src="//cdn.jsdelivr.net/gh/kenwheeler/slick@1.8.1/slick/slick.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/kenwheeler/slick@1.8.1/slick/slick.css" />
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/kenwheeler/slick@1.8.1/slick/slick-theme.css" />

<div class="container">
  <ul class="nav nav-tabs" id="myTab" role="tablist">
    <li class="nav-item"><a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a></li>
    <li class="nav-item"><a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a></li>
    <li class="nav-item"><a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a></li>
  </ul>
  <div class="tab-content" id="myTabContent">
    <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
      <div class="slider slider-home">
        <div>
          <p class="h1">home 1</p>
        </div>
        <div>
          <p class="h1">home 2</p>
        </div>
        <div>
          <p class="h1">home 3</p>
        </div>
        <div>
          <p class="h1">home 4</p>
        </div>
      </div>
    </div>
    <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
      <div class="slider slider-profile">
        <div>
          <p class="h1">profile 1</p>
        </div>
        <div>
          <p class="h1">profile 2</p>
        </div>
        <div>
          <p class="h1">profile 3</p>
        </div>
        <div>
          <p class="h1">profile 4</p>
        </div>
        <div>
          <p class="h1">profile 5</p>
        </div>
      </div>
    </div>
    <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">
      <div class="slider slider-contact">
        <div>
          <p class="h1">contact 1</p>
        </div>
        <div>
          <p class="h1">contact 2</p>
        </div>
        <div>
          <p class="h1">contact 3</p>
        </div>
      </div>
    </div>
  </div>
</div>

For reference, see:

  • Bootstrap Nav Events

    shown.bs.tab
    This event fires on tab show after a tab has been shown. Use event.target and event.relatedTarget to target the active tab and the previous active tab (if available) respectively.

  • Slick Slider Methods

    // Manually refresh positioning of slick
    $('.your-element').slick('setPosition');

    .slick('refresh') also works.

  • If you're using Bootstrap's Collapse component, it has equivalent events:

    shown.bs.collapse
    This event is fired when a collapse element has been made visible to the user (will wait for CSS transitions to complete).



来源:https://stackoverflow.com/questions/48400304/slick-slider-zero-width-in-hidden-container-bootstrap-tab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!