Slick slider not working when initialSlide is set - javascript

I can't figure out why the slides do not slide when I have an initialSlide set. I'm referring to the docs at https://kenwheeler.github.io/slick/, but couldn't figure out what the problem is.
$('.container').slick({
initialSlide: 4,
infinite: false,
slidesToShow: 3,
slidesToScroll: 1
})
* {
box-sizing: border-box;
}
.container {
width: 120px;
}
.slide {
border: 1px solid red;
width: 40px;
}
<link href="https://cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.min.js"></script>
<div class="container">
<div class="slide">1</div>
<div class="slide">2</div>
<div class="slide">3</div>
<div class="slide">4</div>
<div class="slide">5</div>
</div>

You have set the initial slide to 4 (i.e. index 4 is slide #5) - this is the last slide in your carousel. The problem is that your carousel is showing 3 slides, so you want the initial slide to be #3 which has index: 2:
(total slides - slidesToShow) = 5-3 = 2
If you set initialSlide: 2 this will still show the last 3 slides but it also sets up the "previous" button to go to slide #2 which will trigger a scroll. (The Next button won't have any effect of course, because you are showing the last slide and have infinite:false)
Working Example:
$('.container').slick({
initialSlide: 2,
infinite: false,
slidesToShow: 3,
slidesToScroll: 1
})
* {
box-sizing: border-box;
}
.container {
width: 120px;
}
.slide {
border: 1px solid red;
width: 40px;
}
<link href="https://cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.min.js"></script>
<div class="container">
<div class="slide">1</div>
<div class="slide">2</div>
<div class="slide">3</div>
<div class="slide">4</div>
<div class="slide">5</div>
</div>

it is to work
$('.container').slick({
infinite: false,
slidesToShow: 2,
slidesToScroll: 1,
initialSlide: 3
})
you have 5 slides, but the initial one you specified is 4, and at the same time show 3. but the initial 1 is slide 2, the Initial 4 is slide 5, but slidesToShow: 3. the slider doesn't have any spare slides to show
while I was writing the answer it is already given in the comments

Since 2014 initialSlide not working in responsive config, so can use
$('.selector').slick('slickGoTo', 5);

Related

Go back to the prevoius slide using slick and jquery

I have slides that contain multiple calls to actions which open different slide on click
eg if a user is in slide number 1 and clicks a button which opens slide number 5, on clicking button go back it should go back to slide number 1
Here is : LIVE DEMO
HTML
<div class="main">
<div class="slider carousel">
<div><h3>1</h3></div>
<div><h3>2</h3></div>
<div><h3>3</h3></div>
<div><h3>4</h3></div>
<div><h3>5</h3></div>
</div>
<div class="action">
<a id="slide_3" href="#" data-slide="3">go to slide 3</a>
<a id="slide_4" href="#" data-slide="4">go to slide 4</a>
<a id="slide_5" href="#" data-slide="5">go to slide 5</a>
<a id="go-back" href="#" data-slide="5">GO BACK</a>
</div>
</div>
Js
var sliderIndex = 0;
$('.carousel').slick({
slidesToShow: 1,
slidesToScroll: 1,
arrows: false,
fade: true,
});
$("#slide_3").click(function() {
$(".carousel").slick('slickGoTo', parseInt(2));
})
$("#slide_4").click(function() {
$(".carousel").slick('slickGoTo', parseInt(3));
})
$("#slide_5").click(function() {
$(".carousel").slick('slickGoTo', parseInt(4));
})
$('.carousel').on('afterChange', function(e, s, currentSlideIndex) {
sliderIndex = currentSlideIndex-1;
});
$("#go-back").click(function() {
$(".carousel").slick('slickGoTo', parseInt(sliderIndex));
})
Problem: assume I am in slide number 5 Now when I click go to slide 3
and click go back instead of going back to slide number 5 it will go
to slide number 2
The button Go Back in your code just goes back to previous index of current slide. e.g. if current slide is n, it will just go back to n - 1.
If you want Go Back to go back to previous slide that you clicked, you should keep track of current as well as previous index.
Please refer below code -
var currentSliderIndex = 0;
var previousSliderIndex = 0;
$('.carousel').slick({
slidesToShow: 1,
slidesToScroll: 1,
arrows: false,
fade: true,
});
$("#slide_3").click(function(){
$(".carousel").slick('slickGoTo', parseInt(2));
})
$("#slide_4").click(function(){
$(".carousel").slick('slickGoTo', parseInt(3));
})
$("#slide_5").click(function(){
$(".carousel").slick('slickGoTo', parseInt(4));
})
$('.carousel').on('afterChange', function (e, s, currentSlideIndex) {
previousSliderIndex = currentSliderIndex
currentSliderIndex = currentSlideIndex;
});
$("#go-back").click(function () {
$(".carousel").slick('slickGoTo', parseInt(previousSliderIndex));
})
body{
background:#ccc;
}
.main {
font-family:Arial;
width:500px;
display:block;
margin:0 auto;
}
h3 {
background: #fff;
color: #3498db;
font-size: 36px;
line-height: 100px;
margin: 10px;
padding: 2%;
position: relative;
text-align: center;
}
.action{
display:block;
margin:100px auto;
width:100%;
text-align:center;
}
.action a {
display:inline-block;
padding:5px 10px;
background:#f30;
color:#fff;
text-decoration:none;
}
.action a:hover{
background:#000;
}
#go-back{
background-color: green;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.5.9/slick-theme.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.5.9/slick.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.js"></script>
<div class="main">
<div class="slider carousel">
<div><h3>1</h3></div>
<div><h3>2</h3></div>
<div><h3>3</h3></div>
<div><h3>4</h3></div>
<div><h3>5</h3></div>
</div>
<div class="action">
<a id="slide_3" href="#" data-slide="3">go to slide 3</a>
<a id="slide_4" href="#" data-slide="4">go to slide 4</a>
<a id="slide_5" href="#" data-slide="5">go to slide 5</a>
<a id="go-back" href="#" data-slide="5">GO BACK</a>
</div>
</div>
Note - This will only keep track of a single previous slide, if you click back multiple times, it will just keep shuffling between 2 slides.

slick-slider with Corresponding Image Section

I've made a simple slider using Ken Wheeler's slick-slider (https://kenwheeler.github.io/slick/), and I've added an image display function that switches another image below the slider (not the actual slider image) to correspond with the slider. I'd like this for a product carousel that will have a banner image that corresponds with the product in the slick-slider. The below code is functional, but was wondering if there's a cleaner way achieve this. I got hung-up and perhaps long-winded when checking for the inactive slides, and hiding the corresponding images. Thanks.
$(document).ready(function () {
$('.my-slide-wrapper').slick({
dots: true,
infinite: true,
speed: 1,
slidesToShow: 1,
slidesToScroll: 1
});
$("button.slick-arrow").click(function () {
if ($("#slick-slide00").hasClass("slick-active") && (!$("#slick-slide01 #slick-slide02").hasClass("slick-active"))) {
$("#myImage00").addClass("im-showing"),
$("#myImage01").removeClass("im-showing"),
$("#myImage02").removeClass("im-showing");
}
else if ($("#slick-slide01").hasClass("slick-active") && (!$("#slick-slide02 #slick-slide00").hasClass("slick-active"))) {
$("#myImage01").addClass("im-showing"),
$("#myImage02").removeClass("im-showing"),
$("#myImage00").removeClass("im-showing");
}
else {
$("#myImage02").addClass("im-showing"),
$("#myImage01").removeClass("im-showing"),
$("#myImage00").removeClass("im-showing");
}
});
});
Working version on CodePen: https://codepen.io/jakeos/pen/povXPyd
You should check out "Slider Syncing" in the documentation. It does exactly that. In your case, you need to setup both as sliders and use your top slider as the navigation for the bottom one.
I changed your HTML a bit to make it easier to understand
Here's a working fiddle.
HTML
<!-- This is just a slider using Ken Wheeler's slick-slider (https://kenwheeler.github.io/slick/), and I've added an image display function that switches the image below (the slider) to correspond with the slider. It will ultimately be for a product carousel that will have a banner image that corresponds with the product in the slider. -->
<body>
<div class="my-slide-container">
<div id="top-slider" class="my-slide-wrapper">
<img class="slide slide00" src="https://dummyimage.com/300x180/ff0000/ffffff.jpg&text=Slide+1">
<img class="slide slide01" src="https://dummyimage.com/300x180/00ff00/000000.jpg&text=Slide+2">
<img class="slide slide02" src="https://dummyimage.com/300x180/0000ff/ffffff.jpg&text=Slide+3">
</div>
<div id="bottom-slider" class="my-slide-wrapper">
<img class="slide slide00" src="https://dummyimage.com/300x180/ff0000/ffffff.jpg&text=Image+1">
<img class="slide slide01" src="https://dummyimage.com/300x180/00ff00/000000.jpg&text=Image+2">
<img class="slide slide02" src="https://dummyimage.com/300x180/0000ff/ffffff.jpg&text=Image+3">
</div>
</div>
</body>
CSS
.my-slide-container {
margin: 30px;
}
.my-slide-wrapper,
.my-image-wrapper {
margin: 0 auto;
max-width: 300px;
}
img {
max-width: 300px;
width: 100%;
}
.slick-dots li {
margin: 0;
}
.slick-next::before,
.slick-prev::before {
color: #000;
opacity: 1;
}
.my-image {
visibility: hidden;
position: absolute;
}
#myImage00 {
visibility: visible;
}
.im-hiding {
visibility: hidden;
}
.im-showing {
visibility: visible;
}
JS
$(document).ready(function () {
$('#top-slider').slick({
asNavFor: '#bottom-slider',
dots: true,
infinite: true,
speed: 1,
slidesToShow: 1,
slidesToScroll: 1
});
$('#bottom-slider').slick({
arrows: false,
dots: false,
draggable: false,
infinite: true,
speed: 1,
slidesToShow: 1,
slidesToScroll: 1
});
});

Iterate matching elements to control custom slick carousels

I am using slick carousel with some custom code to provide pagination. It's working great but now I want to have multiple carousels per page and although I've found solutions, I'm having trouble getting them to work with the customisations in my code.
There is an example [here] (Multiple Slick Sliders Issue) that iterates over all elements with a particular class and assigns an ID, but I just can't get it working with the custom pagination code I have.
$('.carousel').on('init afterChange', function(event, slick, currentSlide){
let total = $('.carousel .item').length;
var first = $('.slick-active:first > div:first').get(0);
var last = $('.slick-active:last > div:last').get(0);
if($(last).html() == '')
last = $('.slick-active:last > div:not(:empty)').get(0);
let start,end;
$('.slick-slide > div').each(function(i,v){
if(first === $(v).get(0)) {
start = i+1;
}
if(last === $(v).get(0)) {
end = i+1;
}
});
$('.results').html(`Showing ${start} to ${end} of ${total} results`)
})
$('.carousel').slick({
rows: 2,
slidesToShow: 3,
slidesToScroll: 3,
autoplay: false,
arrows: true,
infinite: false,
draggable: false,
prevArrow: $('.prev'),
nextArrow: $('.next')
})
.item {
background: silver;
color: black;
text-align: center;
font-size: 30px;
display: inline;
border: 5px solid white;
}
.nav {
width: 100%;
}
.nav p{
width: 50%;
float: left;
display: block;
text-align: center;
}
.results {
text-align: center;
width: 100%;
padding-top: 10px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick-theme.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.js"></script>
<div class="carousel">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
<div class="item">13</div>
<div class="item">14</div>
<div class="item">15</div>
<div class="item">16</div>
<div class="item">17</div>
<div class="item">18</div>
</div>
<div class="nav">
<p class="prev">prev</p>
<p class="next">next</p>
</div>
<div class="results">
Showing 1 to 9 of [total] results
</div>
You could create a wrapper container to isolate instances
<div class="slider">
<div class="carousel">
<div class="item">1</div>
<div class="item">2</div>
</div>
<div class="nav">
<p class="prev">prev</p>
<p class="next">next</p>
</div>
<div class="results">
Showing 1 to 9 of [total] results
</div>
</div>
Then to initialize use an each loop for isolation
$('.slider').each(function() {
var $slider = $(this),
// arrows within this instance
$nArrow = $slider.find('.next'),
$pArrow = $slider.find('.prev');
// initialize this carousel instance with appropriate arrows
$slider.find('.carousel').slick({
rows: 2,
slidesToShow: 3,
slidesToScroll: 3,
autoplay: false,
arrows: true,
infinite: false,
draggable: false,
prevArrow: $pArrow,
nextArrow: $nArrow
});
})
For the events , look up to the container class and use find() for the elements within that instance
$('.carousel').on('init afterChange', function(event, slick, currentSlide){
var $slider = $(this).parent();
// examples finding elements within this instance
let total = $slider.find('.carousel .item').length;
var first = $slider.find('.slick-active:first > div:first').get(0);
var last = $slider.find('.slick-active:last > div:last').get(0);
// use find for other elements also
......
})

Owl Carousel with conditionals on its options

I've got a dozen galleries and some of them only has one image. This is causing the carousel and page to break because the carousel has loop = true set on it. I'm trying to write a condition to say if there's more than one item in the carousel, to make loop = true else make loop = false. However, I took a shot at it but it doesn't seem to be working.
$(".mbgc-gallery").owlCarousel({
margin: 0,
dots: false,
nav:($(".mbgc-gallery .owl-item").length > 1) ? true: false,
navText: [],
loop:($(".mbgc-gallery .owl-item").length > 1) ? true: false,
autoplay: false,
autoplayHoverPause: true,
responsive: {
0: {
items: 1
},
600: {
items: 1
},
1000: {
items: 1
}
}
});
Can it work like this or do I need to do something after it initializes?
EDIT
I forgot to mention that a page could have more than one gallery on it, so I am not sure if this needs to be wrapped in a .each function or maybe a unique selector? I have data attributes set up on each gallery so it has an unique ID.
Your query in the owlCarousel configuration scans the whole document again. You select all .mbgc-gallerys and then you select all .owl-items of all .mbgc-gallerys.
But you only want to test "this" carousel. Something like this should work:
$(".mbgc-gallery").each(function(index) {
var $gallery = $(this);
var onMultiple = $gallery.children(".owl-item").length > 1 ? true : false;
$gallery.owlCarousel({
loop: onMultiple,
[...]
});
};
edit:
Made a snippet.
Like this?
$('.owl-carousel').each(function(i) {
var ifMultiple = false;
$thisGallery = $(this);
if($thisGallery.children('.item').length > 1) {
ifMultiple = true;
}
$thisGallery.owlCarousel({
loop: ifMultiple,
autoplay: true,
dots: true,
nav: true,
items: 1,
autowidth: true,
nav: false,
dots: false,
responsive:false
})
})
.item {
box-sizing: border-box;
padding: 2rem;
width: 200px;
height: 150px;
background: yellow;
}
.owl-carousel {
border: 1px solid black;
width: 200px !important;
}
<link href="https://owlcarousel2.github.io/OwlCarousel2/assets/owlcarousel/assets/owl.carousel.min.css" rel="stylesheet"/>
<link href="https://owlcarousel2.github.io/OwlCarousel2/assets/owlcarousel/assets/owl.theme.default.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://github.com/OwlCarousel2/OwlCarousel2/raw/develop/dist/owl.carousel.min.js"></script>
<h2>multiple</h2>
<div class="owl-carousel">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
<h2>single</h2>
<div class="owl-carousel">
<div class="item">1</div>
</div>
<h2>multiple</h2>
<div class="owl-carousel">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<h2>single</h2>
<div class="owl-carousel">
<div class="item">1</div>
</div>

Slick Carousel - Disable controls and interactions by external order

I'm learning JavaScript and I've got a simple problem that I don't know how to deal with it.
What I want to achieve is to 'hold' or 'freeze' a slide disabling all kind of possible navigation (keyboard arrows, click and drag, touch interaction) by only clicking a button when the user desires. By clicking this button the user enables or disables the navigation controls with the slider.
So, once clicked this button the user can't navigate on the slides. The user has to click again on the button to enable the controls.
This is what I got so far:
jQuery(document).ready(function($) {
$('.slider').slick({
infinite: true,
fade: false,
centerMode: true,
variableWidth: true,
slidesToShow: 3,
slidesToScroll: 1,
arrows: false,
autoplay: false
});
});
var hold = false;
$('#hold').click(function() {
$(this).attr("class", "active disabled");
if (hold == false) {
$('.slider').slick({
accesibility: false,
draggable: false,
swipe: false,
touchMove: false
});
hold = true;
} else {
$('.slider').slick({
accesibility: true,
draggable: true,
swipe: true,
touchMove: true
});
hold = false;
$("#hold").attr("class", "disabled");
}
});
.card {
margin: 10px;
padding: 50px 100px;
background-color: silver;
color: white;
}
.active {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='//cdn.jsdelivr.net/jquery.slick/1.5.7/slick.min.js' type='text/javascript'></script>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/jquery.slick/1.5.9/slick.css" />
<div class="slider">
<h1 class="card">1</h1>
<h1 class="card">2</h1>
<h1 class="card">3</h1>
<h1 class="card">4</h1>
<h1 class="card">5</h1>
</div>
<button id="hold" class="disabled">HOLD</button>
What could I've been missing?
Your help is really appreciated!
Use slickSetOption to set an individual value live. See the Methods section at http://kenwheeler.github.io/slick/
Below is a working example.
var slider = $("#slider");
slider.slick({
arrows: false,
centerMode: true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
variableWidth: true
});
var hold = false;
$("#hold").click(function() {
slider.slick("slickSetOption", "accessibility", hold);
slider.slick("slickSetOption", "draggable", hold);
slider.slick("slickSetOption", "swipe", hold);
slider.slick("slickSetOption", "touchMove", hold);
hold = !hold;
$(this).toggleClass("disabled");
});
h1 {
background-color: silver;
color: white;
margin: 10px;
padding: 50px 100px;
}
.disabled {
color: red;
}
<link href="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
<div id="slider">
<h1>1</h1>
<h1>2</h1>
<h1>3</h1>
<h1>4</h1>
<h1>5</h1>
</div>
<button id="hold">HOLD</button>

Categories