Задать вопрос
nfobdw143
@nfobdw143

Как выполнять функцию по завершении часто повторяющегося события, а не много раз подряд?

Есть такой код. Всё прекрасно работает, но при прокрутке более чем на один скролл, owl.next(); и owl.prev(); срабатывают многократно, и в результате все слайды пролистываются в конец/начало соответственно. Как сделать, чтоб листалось всегда на один слайд, независимо от того, как сильно пользователь "крутанул" колёсико мыши?
$(document).ready(function() {
   
    var owl = $(".sldr").owlCarousel().data('owlCarousel');

    $(window).on('mousewheel', function(event) {
        
        if(event.deltaY < 0){
            owl.next();           
        }
        if(event.deltaY > 0){
            owl.prev();           
        }
    });  
     
});

Пробовал выставлять false/true при beforeMove: afterMove: и запускать прокрутку только при true, но afterMove выполняется раньше, чем пролистывается слайд.
  • Вопрос задан
  • 671 просмотр
Подписаться 1 Оценить Комментировать
Решения вопроса 2
alexey-m-ukolov
@alexey-m-ukolov Куратор тега JavaScript
Дело в том, что за время вращения колеса мыши, событие mousewheel срабатывает много раз. Соотвественно и обработчик события срабатывает столько же раз.
Чтобы этого избежать, нужно применить debounce обработчика, то есть сделать так, чтобы он выполнился один раз через n миллисекунд после его последнего вызова. Если с момента последнего вызова не прошло n миллисекунд, а обработчик был вызван еще раз, его выполнение откладывается еще на n миллисекунд.
В данном случае, обработчик выполнится через 100 миллисекунд после того, как перестанут поступать события скролла (100 - это просто пример, реальное значение нужно подбирать исходя из ситуации):
$(document).ready(function () {
    var owl = $(".sldr").owlCarousel().data('owlCarousel');

    $(window).on('mousewheel', debounce(function (event) {
        var direction = event.originalEvent.deltaY < 0 ? 'next' : 'prev';
        owl[direction]();
    }, 100));   
});
Код функции debounce
function debounce(func, wait, immediate) {
    var timeout, args, context, timestamp, result;

    var later = function () {
        var last = new Date().getTime() - timestamp;

        if (last < wait && last >= 0) {
            timeout = setTimeout(later, wait - last);
        } else {
            timeout = null;
            if (!immediate) {
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            }
        }
    };

    return function () {
        context = this;
        args = arguments;
        timestamp = new Date().getTime();
        var callNow = immediate && !timeout;
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }

        return result;
    };
}

Реализацию функции debounce я беззастенчиво позаимствовал из библиотеки underscore.
Интерактивный пример
Ответ написан
Комментировать
nfobdw143
@nfobdw143 Автор вопроса
Реализовал таким образом.
$(document).ready(function() {
   
    var speed = 1500    

    var owl = $(".sldr").owlCarousel({
        slideSpeed : speed
    }).data('owlCarousel');

    var f = true;
    function s(){
        f = false;
        function d() {
            f = true;
        }
        setTimeout(d, speed);
    }s();

    $(window).on('mousewheel', function(event) {        
        if(event.deltaY < 0 && f == true){
            owl.next();           
            s();
        }
        if(event.deltaY > 0 && f == true){
            owl.prev();            
            s();
        }
    });    
});
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы