问题
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