jQuery为什么不使用requestAnimationFrame?


73

一些浏览器支持requestAnimationFrame,那么为什么不使用它呢?毕竟,自Google Chrome 10以来一直受支持。尽管如此,jQuery似乎并未使用它。我已经找到有关它的错误报告,但是没有给出真正的解释?我确信jQuery的人有他们的理由。

他们为什么不使用这个很棒的API?


1
尽管jQuery Core不使用requestAnimationFrame,但我在1.8中添加了挂钩,使您可以覆盖setInterval循环,从而可以安装requestAnimationFrame插件
gnarf 2014年

最新版本的jQuery确实使用requestAnimationFramejQuery 3.0在2011
。– Rory O'Kane

Answers:


75

票证#9381中,您可以了解为什么他们requestionAnimationFrame在一段时间后停止使用。

总而言之,问题在于当窗口没有焦点时动画无法运行(浏览器试图减少CPU负载),如果隐藏了窗口,则可以运行动画;如果窗口不可见,则不能运行动画,只是没有焦点。此外,动画队列堆积起来,当窗口重新获得焦点后,事情就发疯了。这将需要对代码进行难看的更改和/或更改人们向动画队列中添加内容的方式。因此决定取消支持,直到有更好的方法可以做到这一点。


29
在jQuery 1.8的,我确信我们可以支持重写定时器循环,并写了一个非常简单的插件,可以将换出setIntervalrequestAnimationFrame- github.com/gnarf37/jquery-requestAnimationFrame
gnarf

47
这主要是由于人们做一些愚蠢的事情setInterval(function{ $('.slideshow).animate(...); }, 3000);。相反,他们应该等待每个动画的结尾将第二个动画排队。这是一个简单的解决方法,如果着陆了,我们所有人都会获得更加流畅,注重电池的动画。
保罗·爱尔兰

12

考虑到这里的其他答案和反对意见,我想在一个简单的幻灯片动画中对此进行测试:

http://brass9.com/nature

截至2013年,此处其他答案中的反对意见似乎不再重要。我已经添加

https://github.com/gnarf/jquery-requestAnimationFrame/blob/master/src/jquery.requestAnimationFrame.js

到我现有的动画代码中,并验证它已打开并影响正在使用的淡入淡出动画。即使在后台窗口中,它也可以在Chrome 30,IE 11和FF 24中可靠地运行。在测试Android 2.3时,它似乎可以使用polyfill并按预期工作。

jQuery 3

jQuery 3.0集成了requestAnimationFrame。基本上,jQuery可以很好地处理它,但是某些用户会调用.setInterval(function() { tag.animate(,将其搞砸了。因此向主要版本发布。jQuery 3不支持并且永远不会支持IE8及更低版本,因此,如果您有IE8用户,请坚持使用jQuery1.x。

CSS过渡

在我的测试中,CPU /电池节省声明requestAnimationFrame是错误的承诺。我看到它的CPU使用率很高,例如,淡入淡出。节省CPU /电池电量的是CSS Transitions,这可能是因为浏览器(尤其是移动浏览器)对您的意图以及对它们的要求有了更强的假设,并且本机代码仍然比Javascript + DOM快。

因此,如果您真的想节省CPU /电池,那么CSS转换非常适合您。IE9及以下版本无法处理它们,并且仍然有大量用户在使用,因此请考虑jquery.transit及其回退到animate页面底部。


2
的确如此,当窗口没有焦点时,至少在Chrome中,我会看到滑块褪色。
大卫·梅斯特

6

在v1.6.2的jQuery源中,我看到requestAnimationFrame它被使用(如果存在)。我还没有详细研究代码,看它是否可以用于所有用途,但是它正在代码的动画部分而不是对的调用中使用setInterval()。以下是1.6.2中的代码:

// Start an animation from one number to another
custom: function( from, to, unit ) {
    var self = this,
        fx = jQuery.fx,
        raf;

    this.startTime = fxNow || createFxNow();
    this.start = from;
    this.end = to;
    this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
    this.now = this.start;
    this.pos = this.state = 0;

    function t( gotoEnd ) {
        return self.step(gotoEnd);
    }

    t.elem = this.elem;

    if ( t() && jQuery.timers.push(t) && !timerId ) {
        // Use requestAnimationFrame instead of setInterval if available
        if ( requestAnimationFrame ) {
            timerId = true;
            raf = function() {
                // When timerId gets set to null at any point, this stops
                if ( timerId ) {
                    requestAnimationFrame( raf );
                    fx.tick();
                }
            };
            requestAnimationFrame( raf );
        } else {
            timerId = setInterval( fx.tick, fx.interval );
        }
    }
},

我尚未使用1.6.4,所以我不知道该版本。如果不是该版本,则肯定存在一些问题,因此将其删除。

编辑:

如果您阅读此博客文章,听起来好像它已从1.6.3中撤出,也许会被放回1.7中,并且被撤回的主要原因是因为它破坏了某些人使用“动画”队列为“错误地”使用(尽管这可能只是个见解)。


请参阅ajax.googleapis.com/ajax/libs/jquery/1/jquery.js我进行了requestionAnimationFrame没有匹配项的搜索
Randomblue

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.