【发布时间】:2015-12-07 21:45:01
【问题描述】:
我尝试不通过编写自己的 scolling 脚本来重新发明轮子,但我发现的所有内容都使用了 jQuery(我不想用它弄乱我的代码),不工作,不支持键滚动或 div滚动...什么都不够好。
我在 Windows 7 上运行:Opera 和 Chrome 滚动不流畅,因此我编写了可提供流畅滚动体验的代码。然而,在默认情况下具有平滑滚动的 Explorer 11 中,我的脚本使它变得非常敏感。我在 Mac OS 上运行 Chrome 的朋友告诉我,那里的滚动也很流畅。
我想我的问题可以通过需要 javascript 滚动增强的浏览器 x 操作系统列表来回答(我无法访问所有内容),或者通过改进我的代码以避免在不需要增强的浏览器下出现丑陋的行为。
必需的功能是
- 没有 jQuery
- 平滑向上/向下键滚动
- 滚动 div,不仅仅是主窗口
- 没有 jQuery(这对我很重要,所以我提到了两次)
- 没有 MooTools,没有框架,只有原生 JS(perharps Modernizr 或其他精益工具是可以接受的)
任何关于代码的建议也很感激(我知道我应该很快使用 requestAnimationFrame)
暂时,我的代码是
// easeOutQuad by Robert Penner
Math.easeOut = function (t, b, c, d) { t /= d; return -c * t*(t-2) + b; };
(function() { // do not mess global space
var
interval, // scroll is being eased
mult = 0, // how fast do we scroll
dir = 0, // 1 = scroll down, -1 = scroll up
steps = 50, // how many steps in animation
length = 30, // how long to animate
keyDelta = 0;
function KeyWheelHandler(e) {
if(e.which!=38 && e.which!=40) return;
keyDelta = e.which==38 ? -1 : 1;
mult = 4;
MouseWheelHandler(e);
}
function MouseWheelHandler(e) {
e.preventDefault(); // prevent default browser scroll
clearInterval(interval); // cancel previous animation
++mult; // we are going to scroll faster
var delta = keyDelta || -Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
if(dir!=delta) { // scroll direction changed
if(!keyDelta) mult = 1; // start slowly
dir = delta;
}
// get the closest scrollable parent
for(var tgt=e.target; tgt!=document.documentElement; tgt=tgt.parentNode) {
var oldScroll = tgt.scrollTop;
tgt.scrollTop+= delta;
if(oldScroll!=tgt.scrollTop) break;
}
var start = tgt.scrollTop;
var end = start + length*mult*delta; // where to end the scroll
var change = end - start; // base change in one step
var step = 2; // current step, not less than 2, see the (t-2) in EaseOut
interval = setInterval(function() {
var pos = Math.easeOut(step++,start,change,steps);
tgt.scrollTop = pos;
if(step>=steps) { // scroll finished without speed up - stop
mult = keyDelta = 0;
clearInterval(interval);
}
},15);
}
if(window.chrome) { // Opera and Chrome
window.addEventListener("mousewheel", MouseWheelHandler);
//window.addEventListener("DOMMouseScroll", MouseWheelHandler); // FF
document.documentElement.addEventListener("keydown", KeyWheelHandler);
}
})();
【问题讨论】:
-
我会使用
wheel事件作为默认值,它是现代跨浏览器版本。顺便说一句,您似乎没有在侦听器中传递事件,因此使用该事件的部分函数将不起作用。 -
没有通过活动?你能具体说一下在哪里吗?
-
window.addEventListener("mousewheel", MouseWheelHandler); -
MouseWheelHandler函数本身将e作为参数,与其他函数一样... -
当然,
e是通过系统调用传递的(旧的 Explorer 除外)。如果我遗漏了什么,请在代码中用 cmets 回答。如果您有更好的解决方案,您可能想回答here,最好带有权威参考的链接。
标签: javascript scroll