Chrome 和 IE 上的断断续续/滞后滚动事件 [英] Choppy/Laggy scroll event on Chrome and IE

查看:30
本文介绍了Chrome 和 IE 上的断断续续/滞后滚动事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to have a content block always be shown to the user, even if he scrolls way down the page. He should also be able to scroll up and down the content block. Here is a fiddle with a stripped down version to show you what I mean:

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

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

One should notice when scrolling down, until reaching the bottom of the red block, it will fix the block on the window, and when scrolling back up, it places it back.

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

In Firefox one can scroll up and down and the fixing/unfixing described above is imperceptible – smooth as silk.

但是,一旦尝试在 Chrome 或 IE 中滚动,滚动事件似乎滞后,并且可以看到块故障"一秒钟.这不是代码延迟——这似乎是浏览器的问题.

Once one tries scrolling in Chrome or IE, though, it seems like the scroll event lags and one can see the block "glitching" for a second. It's not code lag – it seems to be something with the browsers.

有什么办法可以解决这个问题吗?我已经无计可施了.

Is there any way to fix this? I'm at my wit's end.

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

I'd appreciate suggestions on how I can achieve the same effect in a different way...thanks

推荐答案

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

Since JavaScript runs in the same thread as the UI, a scroll event callback can block the UI-thread and thus cause lag. You need to throttle the scroll event listener because some browsers fire a lot of them. Especially if you're on OS X with an analog scroll device. Since you do a lot of height calculations in your listener, it will trigger a reflow (very expensive) for every scroll event that is fired.

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

To throttle the listener, you have to prevent the listener from firing every time. Usually you wait until the browser doesn't trigger an event for x milliseconds, or have a minimum time between calling your callback. Try adjusting the value to see the effect. Even 0 milliseconds can help, since it will delay the execution of the callback until the browser has time (usually 5-40 ms).

切换类以在状态(静态和固定位置)之间切换,而不是在 JavaScript 中对其进行硬编码也是一种很好的做法.然后你就可以更清晰地分离关注点,并且避免潜在的额外错误重绘(请参阅浏览器是智能的"部分).(jsfiddle 示例)

It's also a good practice to toggle a class to switch between states (static and fixed position) instead of hard-coding it in JavaScript. Then you have a cleaner separation of concerns and avoid potential extra redraws by mistake (see "Browsers are smart" section). (example on 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 插件,它有一个简单的并优雅地解决您的问题.只需定义当用户滚动到某个航点时的回调.

jQuery Waypoints Since you're already using jQuery, I would have a look at the jQuery Waypoints plugin which has a simple and elegant solution to your problem. Just define a callback when the user scrolls to a certain waypoint.

示例:(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
    });
});

这篇关于Chrome 和 IE 上的断断续续/滞后滚动事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆