jQuery 检查用户是否正在使用触控板滚动?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12486141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check if user is scrolling with trackpad?
提问by Cody
I have created a site where users are able to scroll through a gallery using mouse scroll or arrow up/down. It is working like I want it to, and changing one image pr scroll when scrolling with a mouse. But if the user is scrolling with a trackpad it is almost impossible to scroll a single image at a time.
我创建了一个网站,用户可以在其中使用鼠标滚动或向上/向下箭头滚动浏览图库。它像我想要的那样工作,并在使用鼠标滚动时更改一个图像 pr 滚动。但是如果用户使用触控板滚动,一次滚动单个图像几乎是不可能的。
So my question is: Is there a way to check if the user is scrolling by trackpad, and then changing the behavior of the scrolling, so it becomes less sensitive, and thereby easier to scroll a single image at a time?
所以我的问题是:有没有办法检查用户是否通过触控板滚动,然后更改滚动行为,使其变得不那么敏感,从而更容易一次滚动单个图像?
I am not very good at jquery, my solution so far has been put together from a couple of scripts:
我不太擅长 jquery,到目前为止,我的解决方案是由几个脚本组合而成的:
http://jsfiddle.net/MukuMedia/PFjzX/33/
http://jsfiddle.net/MukuMedia/PFjzX/33/
Hope someone can help me :)
希望可以有人帮帮我 :)
采纳答案by HellaMad
No, this is not possible. The only solution I can think of is set a limit on the scrolling speed. I'm not going to try and decipher your code but I'd recommend making a timedOut
variable initialized to zero which is set to one every time you scroll to a new image. Use a setTimeout()
to set it back to zero after, say, 50ms. Before you scroll to a new image, check this timedOut
variable and only scroll if it's zero. (Make sure you place your setTimeout
inside of the timedOut
check, otherwise it will be constantly called every time the mousewheel moves, which is not what you want.)
不,这是不可能的。我能想到的唯一解决方案是对滚动速度设置限制。我不会尝试破译您的代码,但我建议您将timedOut
变量初始化为零,每次滚动到新图像时都将其设置为 1。使用 asetTimeout()
在 50 毫秒后将其设置回零。在滚动到新图像之前,请检查此timedOut
变量并且仅在它为零时才滚动。(确保您将支票放在setTimeout
内部timedOut
,否则每次鼠标滚轮移动时都会不断调用它,这不是您想要的。)
回答by YoannM
I found out that the magic number here was 40.
我发现这里的神奇数字是 40。
It seems that with the trackpad (probably with the magic mouse too) the delta get increased 40 times.
似乎使用触控板(也可能使用魔术鼠标),增量增加了 40 倍。
And it stays that way even if you take back your normal mouse and scroll with it later.
即使您收回普通鼠标并稍后滚动鼠标,它也会保持这种状态。
So what I did, using the jquery mousewheel plugin:
所以我做了什么,使用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.
});
回答by posit labs
This is pretty much what DC_ suggested. Figured I'd post this since it's an actual implementation.
这几乎是 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);
回答by David Fari?a
I found a solution which detects if the user is using a touchpad. It works great and has only two tiny drawbacks.
我找到了一个检测用户是否使用触摸板的解决方案。它工作得很好,只有两个小缺点。
Firstly it detects the mousescroll after the first fired event, so theres one click with the mousewheel which does nothing. But this is only the first time. Then we can cache the value which leads to the second tiny problem. When the user has a trackpad and a mouse with wheel it detects whatever gets used first. To me those problems are negligible. Here the code
首先,它在第一个触发事件后检测 mousescroll,因此单击鼠标滚轮,什么也不做。但这只是第一次。然后我们可以缓存导致第二个小问题的值。当用户有一个触控板和一个带滚轮的鼠标时,它会检测首先使用的任何东西。对我来说,这些问题可以忽略不计。这里的代码
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);
回答by armanox
I ran into a similar problem with a "section-change" plugin that I created. I ended resolving it with an "animation" variable: the wheel action only works if this variable is set to 'false' and once this is triggered the variable switches to 'true', then I would switch the variable back to 'false' once the animation is completed. Hope this helps!
我在创建的“部分更改”插件中遇到了类似的问题。我用“动画”变量结束了它的解析:滚轮动作仅在此变量设置为“假”时才有效,一旦触发该变量,变量将切换为“真”,然后我会将变量切换回“假”一次动画完成。希望这可以帮助!