Как исправить проблему с распознаванием паузы у карусели при клике на навигационные элементы?

Рейтинг: 0Ответов: 2Опубликовано: 07.02.2023

Есть сайт на wordpress с установленным плагином SiteOrigin Widgets Bundle, который имеет в своём составе карусель, построенной на библиотеке слайдера slick.

У этой карусели есть проблема при автоматической прокрутке: если выждать некоторое время до перехода к следующему слайду (но меньшее, чем необходимо для пролистывания) и самому нажать на навигационные элементы (стрелки или буллеты), то время паузы во время следующего слайда окажется меньше, чем заложено в таймауте, т.е. посетитель не успевает толком просмотреть слайд как он уже прокрутился вперёд.

Полагаю, что такое поведение связано с кастомной реализаций прокрутки в данной карусели в этом фрагменте кода

// Set up Autoplay. We use a custom autoplay rather than the Slick
// autoplay to account for the (sometimes) non-standard nature of our
// navigation that Slick has trouble accounting for.
if ( carouselSettings.autoplay ) {
    var interrupted = false;
    var autoplayNav = $$.parent().parent().find( '.sow-carousel-' + ( $$.data( 'dir' ) == 'ltr' ? 'next' : 'prev' ) );
    // Check if this is a Block Editor preview, and if it is, don't autoplay.
    if ( ! $( 'body' ).hasClass( 'block-editor-page' ) ) {
        setInterval( function() {
            if ( ! interrupted ) {
                autoplayNav.trigger( 'click' );
            }
        }, carouselSettings.autoplaySpeed );

        if ( carouselSettings.pauseOnHover ) {
            $items.on('mouseenter.slick', function() {
                interrupted = true;
            } );
            $items.on( 'mouseleave.slick', function() {
                interrupted = false;
            } );
        }
    }
}

Как можно устранить проблему и наладить отсчет времени на прокрутку с момента переключения слайда независимо автоматически он прокрутился или принудительно по клику пользователем? Полный gist c кодом карусели находится здесь

Ответы

▲ 0Принят

Решением было сбросить таймер внутри ивента переключения стрелок:

$$.parent().parent().find( '.sow-carousel-previous, .sow-carousel-next' ).on( 'click touchend', function( e, refocus ) {
    ....

    // Reset autoplay
    clearInterval(autoplayInterval);
    autoplayInterval = autoplay();
});

И разместить обработчик буллетов

else if ( carouselSettings.dots ) {
        $$.find( '.slick-dots li' ).on( 'click touchend', function() {
           // Reset autoplay
     clearInterval(autoplayInterval);
     autoplayInterval = autoplay();
        });
}

сразу после

if ( carouselSettings.dots && ( $$.data( 'variable_width' ) || $$.data( 'carousel_settings' ).theme ) ) {...}

▲ 1

Думаю, этот вариант решения вам подойдет

if (carouselSettings.autoplay) {
    var autoplayNav = $$.parent().parent().find('.sow-carousel-' + ($$.data('dir') == 'ltr' ? 'next' : 'prev'));
    // Check if this is a Block Editor preview, and if it is, don't autoplay.
    if (!$('body').hasClass('block-editor-page')) {
        let timer;

        function nextTick() {
            timer = setInterval(function () {
                autoplayNav.trigger('click');
            }, carouselSettings.autoplaySpeed);
        }
        nextTick();

        if (carouselSettings.pauseOnHover) {
            $items.on('mouseenter.slick', function () {
                clearInterval(timer);
            });
            $items.on('mouseleave.slick', function () {
                nextTick()
            });
        }
    }
}

У вас выставлялся флаг "менять/не менять" данные в цикле, однако это не приводило к остановке таймера или его остановке на паузу.

При наведении мыши, надо сбрасывать таймер. Когда мышь покинула слайдер, запускать