OSX инерция прокрутки вызывает колесо мыши.JS, чтобы зарегистрировать несколько событий мыши при малейшем движении прокрутки


У меня есть довольно стандартный экземпляр Flexslider, над которым я работаю. Flexslider хорошо сочетается с jquery.мышиное колесо.Яш плагин, позволяющий слайдов на события мыши.

Однако, Mac OSX и другие используют инерцию для прокрутки эффектов, что делает его практически невозможно прокрутить только один слайд влево или вправо. Общий эффект заключается в том, что даже малейшее движение прокрутки в этих ситуациях вызывает несколько событий колесика мыши и прокручивает ползунок несколько изображений слева или справа. Очевидно, этого не может быть!

Я думаю, что решение заключается в использовании подчеркивания .js - в частности, функция "debounce". Однако я относительно неопытен в JS / jQuery и не могу понять, как его реализовать.

Из документации подчеркивания:

Дебоунс: _.debounce(function, wait, [immediate])

Создает и возвращает a новая дебютированная версия переданной функции, которая отложит ее исполнение до конца подождите миллисекунд, прошедших с момента последнего время, когда он был вызван. Полезно для реализации поведения, которое должно быть только происходит после того, как вход перестал поступать. Например: оказание предварительный просмотр комментария Markdown, пересчет макета после окна перестал изменяться размер, и так далее.

Передайте значение true для параметра immediate, чтобы вызвать срабатывание debounce. функция на переднем, а не на заднем крае ожидания интервал. Полезно в таких обстоятельствах, как предотвращение случайных дважды нажимает на кнопку "Отправить" от выстрела во второй раз.

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

Вот код, который я использую для инициализации flexslider:

// MOUSEWHEEL FIX:

function debounceEffect() { // apply debounce to mousewheel here

}

// Initialize FlexSlider
$(window).load(function() {     
    $('div.flexslider').flexslider({
        animation:'slide',
        controlNav:true,
        mousewheel:true,
        pauseOnHover:true,
        direction:'horizontal',
        animationSpeed:500,
        slideshowSpeed:5000,
        after:debounceEffect
    });
});

К сожалению, я не могу понять, как применить функцию debounce к событию mousewheel. Я думаю, что просто недостаточно хорошо понимаю движущиеся части.

Вот соответствующий бит кода из плагина flexslider :

    // MOUSEWHEEL:
    if (vars.mousewheel) {
      slider.bind('mousewheel', function(event, delta, deltaX, deltaY) {
        event.preventDefault();
        var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev');
        slider.flexAnimate(target, vars.pauseOnAction);
      });
    }

Я могу отредактировать это, чтобы включить некоторые из плагинов mousewheel код также, если это важно, или вы можете проверить его на github.

Я был бы признателен за любую помощь в этом!

2 4

2 ответа:

Я думаю, что главная проблема заключается в том, что вы не сможете применить дебоунсинг как последействие, или, по крайней мере, я не знаю, как это сделать. Давайте поговорим о том, как работают части:

Когда вы вызываете $('div.flexslider').flexslider({ .. }, jQuery находит все элементы, такие как div.flexslider (как обычно), а затем добавляет к ним flexslider. flexslider добавляет все механизмы, чтобы сделать его слайдером, включая настройку событий привязки. Это фактические события привязки сами по себе, которые вам нужно разоблачить.

Похоже, ты подобрался довольно близко. поиск соответствующего кода привязки flexslider. Я думаю, что в идеале вы хотели бы вот чего:

if (vars.mousewheel) {
  slider.bind('mouse wheel', _.debounce(function(…) {
   // usual flex slider code.
  }), 300);
}

Я не уверен, как бы вы на самом деле ввели этот debounce без прямого редактирования кода flexslider.

Вы, вероятно, могли бы отказаться от самого плагина колеса мыши, Если вы хотите глобально повлиять на события mousewheel (что, я думаю, вы можете сделать). Я думаю, что вам придется обернуть обработчик в debounce, а затем передать обработчик debounce в addEventListener иremoveEventListener .

Похоже, эта проблема все еще существует.

Я получил некоторые хорошие результаты, используя этот плагин debounce и изменяя flexslider.js так что это следующее:

slider.bind('mousewheel', $.debounce( 100, true, function(event, delta, deltaX, deltaY){
     event.preventDefault();
     var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev');

    slider.flexAnimate(target, slider.vars.pauseOnAction);
}));