28

我试图让内容块始终显示给用户,即使他向下滚动页面。他还应该能够上下滚动内容块。这是一个精简版本的小提琴,向您展示我的意思:

http://jsfiddle.net/9ehfV/2/

向下滚动时要注意,直到到达红色块的底部,它会将块固定在窗口上,向上滚动时将其放回原处。

在 Firefox 中,可以上下滚动,上面描述的固定/取消固定是不可察觉的——像丝绸一样光滑。

但是,一旦尝试在 Chrome 或 IE 中滚动,滚动事件似乎就会滞后,并且可以看到块“故障”一秒钟。这不是代码延迟——这似乎与浏览器有关。

有没有什么办法解决这一问题?我无计可施。

我很感激有关如何以不同方式实现相同效果的建议...谢谢

4

2 回答 2

47

由于 JavaScript 在与 UI 相同的线程中运行,滚动事件回调可能会阻塞 UI 线程,从而导致延迟。您需要限制滚动事件侦听器,因为某些浏览器会触发很多事件侦听器。特别是如果您在 OS X 上使用模拟滚动设备。由于您在侦听器中进行了大量高度计算,因此它会为每个触发的滚动事件触发重排(非常昂贵)。

要限制侦听器,您必须防止侦听器每次都触发。通常你会等到浏览器在 x 毫秒内没有触发事件,或者在调用你的回调之间有最短时间。尝试调整值以查看效果。即使是 0 毫秒也有帮助,因为它会延迟回调的执行,直到浏览器有时间(通常是 5-40 毫秒)。

切换类以在状态(静态和固定位置)之间切换而不是在 JavaScript 中对其进行硬编码也是一个好习惯。然后,您可以更清晰地分离关注点并避免潜在的额外重绘错误(请参阅“浏览器很聪明”部分)。(关于 jsfiddle 的示例

等待 x 毫秒的暂停

// 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 毫秒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
    });
});
于 2012-06-14T18:47:20.193 回答
1

您是否尝试过一些用于滚动条的 jquery 插件或使用动画向下和向上滚动?它将强制所有浏览器以相同的方式工作(或关闭足够的)..

发生的事情是firefox(至少v12)有一个“本机”滚动动画。当您浏览任何 URL 时,您会注意到滚动操作的流畅度,这在其他浏览器(如 Chrome 或 IE)中未实现。

jquery滚动插件的例子:

于 2012-06-12T16:23:32.143 回答