Проверьте, прокручивает ли пользователь трекпад?
Я создал сайт, где пользователи могут прокручивать галерею, используя прокрутку мыши или стрелки вверх / вниз. Он работает так, как я хочу, и изменяет одну прокрутку изображения при прокрутке с помощью мыши. Но если пользователь прокручивает трекпад, практически невозможно прокрутить одно изображение за раз.
Итак, мой вопрос: есть ли способ проверить, прокручивает ли пользователь трекпад, а затем изменить поведение прокрутки, чтобы он стал менее чувствительным и, следовательно, легче прокручивать одно изображение за раз?
Я не очень хорош в 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, я думаю, это зависит от скорости колесика мыши)