我正在尝试向用户显示内容块,即使他向下滚动页面也是如此。他还应该能够在内容块中上下滚动。这是一个带有精简版的小提琴,向您展示我的意思:
当向下滚动时,应该注意到,直到到达红色块的底部,它会将块固定在窗口上,当向上滚动时,它会将其放回原位。
在Firefox中,可以向上和向下滚动,上面描述的固定/解除固定是不可察觉的 - 像丝绸一样光滑。
一旦尝试在Chrome或IE中滚动,看起来滚动事件似乎滞后,人们可以看到该块“故障”一秒钟。这不是代码延迟 - 它似乎与浏览器有关。
有什么方法可以解决这个问题吗?我的智慧结束了。
我很欣赏有关如何以不同的方式达到同样效果的建议......谢谢
答案 0 :(得分:44)
由于JavaScript在与UI相同的线程中运行,因此滚动事件回调可以阻止UI线程,从而导致延迟。您需要限制滚动事件侦听器,因为某些浏览器会激活它们。特别是如果你在OS X上使用模拟滚动设备。由于您在侦听器中进行了大量的高度计算,因此每个触发的滚动事件都会it will trigger a reflow(非常昂贵)。
要限制侦听器,您必须每次都阻止侦听器触发。通常,您要等到浏览器不会触发x毫秒的事件,或者在调用回调之间有最短的时间。尝试调整值以查看效果。即使0毫秒也可以提供帮助,因为它会延迟回调的执行,直到浏览器有时间(通常为5-40毫秒)。
切换类以在状态(静态和固定位置)之间切换而不是在JavaScript中对其进行硬编码也是一种很好的做法。然后你可以更清晰地分离关注点和avoid potential extra redraws by mistake(参见“浏览器很聪明”部分)。 (example on jsfiddle)
等待暂停x ms
// return a throttled function
function waitForPause(ms, callback) {
var timer;
return function() {
var self = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
callback.apply(self, args);
}, ms);
};
}
this.start = function() {
// wrap around your callback
$window.scroll( waitForPause( 30, self.worker ) );
};
等待至少x ms (jsfiddle)
function throttle(ms, callback) {
var timer, lastCall=0;
return function() {
var now = new Date().getTime(),
diff = now - lastCall;
console.log(diff, now, lastCall);
if (diff >= ms) {
console.log("Call callback!");
lastCall = now;
callback.apply(this, arguments);
}
};
}
this.start = function() {
// wrap around your callback
$window.scroll(throttle(30, self.worker));
};
jQuery Waypoints 既然你已经在使用jQuery了,我会看一下jQuery Waypoints插件,它有一个简单而优雅的解决方案来解决你的问题。只需在用户滚动到某个航路点时定义一个回调。
示例:(jsfiddle)
$(document).ready(function() {
// throttling is built in, just define ms
$.waypoints.settings.scrollThrottle = 30;
$('#content').waypoint(function(event, direction) {
$(this).toggleClass('sticky', direction === "down");
event.stopPropagation();
}, {
offset: 'bottom-in-view' // checkpoint at bottom of #content
});
});
答案 1 :(得分:1)
您是否尝试过滚动条的jquery插件或使用动画向下滚动?它将强制所有浏览器以相同的方式工作(或关闭enought)..
firefox(至少v12)有一个“原生”滚动动画。当您浏览任何URL时,您可以注意到滚动操作的平滑性,而这在其他浏览器中没有实现,例如Chrome或IE。
jquery滚动插件的示例: