Проверьте, прокручивает ли пользователь трекпад?

Я создал сайт, где пользователи могут прокручивать галерею, используя прокрутку мыши или стрелки вверх / вниз. Он работает так, как я хочу, и изменяет одну прокрутку изображения при прокрутке с помощью мыши. Но если пользователь прокручивает трекпад, практически невозможно прокрутить одно изображение за раз.

Итак, мой вопрос: есть ли способ проверить, прокручивает ли пользователь трекпад, а затем изменить поведение прокрутки, чтобы он стал менее чувствительным и, следовательно, легче прокручивать одно изображение за раз?

Я не очень хорош в jquery, мое решение до сих пор было составлено из нескольких скриптов:

http://jsfiddle.net/MukuMedia/PFjzX/33/

Надеюсь, кто-нибудь может мне помочь:)

6 ответов

Решение

Нет, это невозможно. Единственное решение, которое я могу придумать, это установить ограничение скорости прокрутки. Я не собираюсь пытаться расшифровать ваш код, но я бы порекомендовал сделать timedOut переменная инициализируется нулем, который устанавливается в единицу каждый раз, когда вы переходите к новому изображению. Использовать setTimeout() чтобы обнулить его, скажем, через 50 мс. Прежде чем перейти к новому изображению, проверьте это timedOut переменная и только прокрутка, если она равна нулю. (Убедитесь, что вы разместите свой setTimeout внутри timedOut проверьте, в противном случае он будет постоянно вызываться при каждом перемещении колесика мыши, а это не то, что вам нужно.)

Я узнал, что магическое число здесь было 40.

Кажется, что с помощью трекпада (возможно, и с помощью волшебной мыши) дельта увеличивается в 40 раз.

И так будет, даже если вы вернете свою обычную мышь и прокрутите ее позже.

Итак, что я сделал, используя плагин jquery mousewheel:

b.mousewheel(function(evt,delta,deltaX,deltaY){
    if(Math.abs(deltaY)>=40)
        deltaY/=40;
    if(Math.abs(deltaX)>=40)
        deltaX/=40;

    //Do your stuff here.
});

Это почти то, что предложил DC_. Я решил опубликовать это, потому что это фактическая реализация.

// similar to _.debounce, but was having issues with it, so I made this.
function rateLimit(func, time){
        var callback = func,
                waiting = false,
                context = this;
        var rtn = function(){
            if(waiting) return;
            waiting = true;
            var args = arguments;
            setTimeout(function(){
                waiting = false;
                callback.apply(context, args);
            }, time);
        };
        return rtn;
    }

    function onWheel(e){
      // Add your code here
    }

    // will only fire a maximum of 10 times a second
    var debouncedOnWheel = rateLimit(onWheel, 100);
    window.addEventListener("wheel", debouncedOnWheel);

Я столкнулся с подобной проблемой с плагином "изменение раздела", который я создал. Я закончил разрешать его с помощью переменной "animation": действие wheel работает только в том случае, если для этой переменной установлено значение "false", и после ее запуска переменная переключается на "true", тогда я бы однажды переключил переменную обратно на "false" анимация завершена. Надеюсь это поможет!

Я нашел решение, которое определяет, использует ли пользователь тачпад. Он прекрасно работает и имеет только два крошечных недостатка.

Во-первых, он обнаруживает прокручивание мышки после первого события, поэтому один клик с колесом мыши ничего не делает. Но это только в первый раз. Затем мы можем кэшировать значение, которое приводит ко второй крошечной проблеме. Когда у пользователя есть трекпад и мышь с колесом, он обнаруживает, что используется первым. Для меня эти проблемы незначительны. Вот код

var scrolling = false;
var oldTime = 0;
var newTime = 0;
var isTouchPad;
var eventCount = 0;
var eventCountStart;

var mouseHandle = function (evt) {
    var isTouchPadDefined = isTouchPad || typeof isTouchPad !== "undefined";
    console.log(isTouchPadDefined);
    if (!isTouchPadDefined) {
        if (eventCount === 0) {
            eventCountStart = new Date().getTime();
        }

        eventCount++;

        if (new Date().getTime() - eventCountStart > 50) {
                if (eventCount > 5) {
                    isTouchPad = true;
                } else {
                    isTouchPad = false;
                }
            isTouchPadDefined = true;
        }
    }

    if (isTouchPadDefined) { // in this if-block you can do what you want
        // i just wanted the direction, for swiping, so i have to prevent
        // the multiple event calls to trigger multiple unwanted actions (trackpad)
        if (!evt) evt = event;
        var direction = (evt.detail<0 || evt.wheelDelta>0) ? 1 : -1;

        if (isTouchPad) {
            newTime = new Date().getTime();

            if (!scrolling && newTime-oldTime > 550 ) {
                scrolling = true;
                if (direction < 0) {
                    // swipe down
                } else {
                    // swipe up
                }
                setTimeout(function() {oldTime = new Date().getTime();scrolling = false}, 500);
            }
        } else {
            if (direction < 0) {
                // swipe down
            } else {
                // swipe up
            }
        }
    }
}

document.addEventListener("mousewheel", mouseHandle, false);
document.addEventListener("DOMMouseScroll", mouseHandle, false);

Ни один из ответов не сработал для меня, но вот что я сделал:

      function detectTrackPadHorizontalMovement(event) {
    if (Math.abs(event.deltaY) < 5) return true
    if (Math.abs(event.deltaX) !== 0) return true
    return false
}

Сенсорная панель почти всегда производит дельту x и y, где колесико мыши x равно -0 Дельта сенсорной панели меньше 5, где колесико мыши больше 5 (для меня обычно около 13, я думаю, это зависит от скорости колесика мыши)

Другие вопросы по тегам