Reputation: 2298
I want to be able to jump to the next slide instantly and without any further transition.
Currently this only works in between the transitions., but how to make it work during a transition? In other words I ideally need something like $('.slick').slick("finishTransition")
See fiddle.
<div class="slick">
<img src="http://placekitten.com/g/200/200" />
<img src="http://placekitten.com/g/200/200" />
<img src="http://placekitten.com/g/200/200" />
<img src="http://placekitten.com/g/200/200" />
<img src="http://placekitten.com/g/200/200" />
</div>
<a href="javascript:;" class='slick-next'>next</a>
$('.slick').slick({
infinite: true,
speed: 5000,
slidesToShow: 1,
centerMode: true,
variableWidth: true,
autoplay: true,
autoplaySpeed: 200,
prevArrow: '',
nextArrow: ''
});
$('.slick-next').click(function(){
$('.slick').slick("slickSetOption", 'speed', 1, true)
$('.slick').slick("slickNext")
$('.slick').slick("slickSetOption", 'speed', 5000, true)
});
Upvotes: 4
Views: 10708
Reputation: 31
after lots of head + wall banging, I've got a solution to this.
slick 1.8.1 jQuery 1.12.4
Basically you need to intercept the click event before Slick.js gets it, stopPropagation and preventDefault immediately using "true" on the click event handler, then pause, save the current settings, swap the settings and go to the next / prev slide, then reapply the original settings and start the autoplay again.
See below:
/* fast manual prev and next transitions */
document.addEventListener('click', function(event) {
var direction;
var classList = Array.from(event.target.classList);
if ( classList.includes('slick-arrow') ) {
event.preventDefault();
event.stopImmediatePropagation();
if ( classList.includes('slick-next') ) {
direction = 'next';
} else if ( classList.includes('slick-prev') ) {
direction = 'prev';
}
slickManualChange(event, direction);
}
}, true);
const slickManualChange = function(event, direction){
var SSclasses = $(event.target).closest('[class*="your-class"]')[0].classList;
var selector = '.' + Array.from(SSclasses).filter(classes => classes.includes('your-class'))[0];
var autoplay = $(selector).slick("slickGetOption", 'autoplay');
var speed = $(selector).slick("slickGetOption", 'speed');
var waitForAnimate = $(selector).slick("slickGetOption", 'waitForAnimate');
var useCSS = $(selector).slick("slickGetOption", 'useCSS');
$(selector).slick("slickPause");
$(selector).slick("slickSetOption", 'autoplay', false, true);
$(selector).slick("slickSetOption", 'speed', 0, true);
$(selector).slick("slickSetOption", 'waitForAnimate', false, true);
$(selector).slick("slickSetOption", 'useCSS', false, true);
if ( direction === 'next' ) {
$(selector).slick("slickNext");
} else if ( direction === 'prev' ) {
$(selector).slick("slickPrev");
}
$(selector).slick("slickSetOption", 'autoplay', autoplay, true);
$(selector).slick("slickSetOption", 'speed', speed, true);
$(selector).slick("slickSetOption", 'waitForAnimate', waitForAnimate, false);
$(selector).slick("slickSetOption", 'useCSS', useCSS, false);
$(selector).slick("slickPlay");
}
You can simplify the selector if you always use the same one, but I use variants of a similar one for different slideshows on each page, and different pages.
Hope this helps.
Upvotes: 0
Reputation: 900
The following code should work. You have to dynamically disable the waitForAnimate option. And clearing setInterval's was needed as the autoplay was getting messed up. That might need some tweaking.
https://jsfiddle.net/ps41xqh4/47/
$('.slick').slick({
infinite: true,
speed: 5000,
slidesToShow: 1,
centerMode: true,
variableWidth: true,
autoplay: true,
autoplaySpeed: 300,
prevArrow: '',
nextArrow: '',
waitForAnimate: true
});
$('.slick-next').click(function(event) {
for (i = 0; i < 9999; i++) {
window.clearInterval(i);
}
$('.slick').slick("slickSetOption", 'autoplay', false, true)
$('.slick').slick("slickSetOption", 'speed', 1, true)
$('.slick').slick("slickSetOption", 'waitForAnimate', false, false)
$('.slick').slick("slickGoTo", $('.slick').slick('slickCurrentSlide'))
$('.slick').one('afterChange', function(e, s, c) {
$('.slick').slick("slickSetOption", 'speed', 5000, true)
$('.slick').slick("slickSetOption", 'autoplay', true, true)
$('.slick').slick("slickSetOption", 'waitForAnimate', true, false)
});
});
Upvotes: 1
Reputation: 792
try to set the autoplay to false:
$('.slick').slick({
infinite: true,
speed: 5000,
slidesToShow: 1,
centerMode: true,
variableWidth: true,
autoplay: false,
prevArrow: '',
nextArrow: ''
});
$('.slick-next').click(function(){
$('.slick').slick("slickSetOption", 'speed', 1, true)
$('.slick').slick("slickNext")
$('.slick').slick("slickSetOption", 'speed', 5000, true)
});
Upvotes: 0
Reputation: 4117
After some digging I found an additional config option which should allow you to use the internal methods as you wish whilst animating.
waitForAnimate: false,
I've included your fiddle with this change only and it seems to provide the desired result.
It's documented on the projects github page: https://github.com/kenwheeler/slick/
You will probably need to experiment with how to make it performant, but this setting will ultimately free up the requests you make during animations.
https://jsfiddle.net/uhkagr7n/
The full config for reference:
$('.slick').slick({
infinite: true,
speed: 5000,
slidesToShow: 1,
centerMode: true,
variableWidth: true,
autoplay: true,
autoplaySpeed: 200,
prevArrow: '',
nextArrow: '',
waitForAnimate: false,
});
Upvotes: 7