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

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

问题描述

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

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



人们应该注意当向下滚动时,直到达到红色块的底部,它将修复窗口中的块,并且当向后滚动时,它将其放回。

在Firefox中,人们可以上下滚动,上面描述的固定/解除固定不易察觉 - 像丝绸一样光滑。

<然而,一旦有人尝试在Chrome或IE中滚动,看起来像滚动事件滞后,人们可以看到该块闪烁一秒钟。这不是代码滞后 - 它似乎与浏览器有关。



有什么方法可以解决这个问题吗?我在智慧的结尾。



我很感激我如何以不同的方式达到相同效果的建议......谢谢

解决方案

由于JavaScript和UI在同一个线程中运行,滚动事件回调会阻塞UI线程,从而导致滞后。您需要调节滚动事件侦听器,因为有些浏览器触发了很多事件。特别是如果你在OS X上使用模拟滚动设备。由于您在听众中进行了很多高度计算,所以它会触发回流(非常昂贵)为每个被触发的滚动事件。



为了节制监听器,你必须防止监听器每次都被触发。通常你要等到浏览器在x毫秒内不触发事件,或者在调用你的回调函数之间有一段时间。尝试调整值以查看效果。即使是0毫秒也可以提供帮助,因为它会延迟回调的执行时间,直到浏览器有时间(通常为5-40毫秒)。



切换一个在状态之间切换的类(静态和固定位置),而不是在JavaScript中对它进行硬编码。然后你有一个清晰的问题分离和避免潜在的额外重绘错误(请参阅浏览器很聪明部分)。 ( jsfiddle

等待xms的停顿


$ b

  //返回一个被限制的函数
函数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(){
//绕回你的回调
$ window.scroll(waitForPause(30,self.worker));
};

等待至少x ms

   函数throttle(ms,回调){
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);
}
};

$ b $ this.start = function(){
//绕回你的回调
$ window.scroll(throttle(30,self.worker));
};

jQuery Waypoints
由于您已经在使用jQuery,我会看看
jQuery Waypoint 插件,它有一个简单而优雅的解决方案来解决您的问题。只需在用户滚动到某个航点时定义回调。



示例:( jsfiddle

  $(document).ready(function(){ 
// throttling内置,只需定义ms
$ .waypoints.settings.scrollThrottle = 30;
$ b $('#content')。waypoint(function(event,方向){
$(this).toggleClass('sticky',direction ===down);
event.stopPropagation();
},{
offset: 'bottom-in-view'//检查点位于#content
});
});


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.

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

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

解决方案

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.

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).

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)

Wait for a pause of 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 ) );
};

Wait at least 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 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.

Example: (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上的Choppy / Laggy滚动事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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