【问题标题】:Why doesn't jQuery use requestAnimationFrame?为什么 jQuery 不使用 requestAnimationFrame?
【发布时间】:2011-12-21 10:19:36
【问题描述】:

有些浏览器支持requestAnimationFrame,为什么不用呢?毕竟是supported since Google Chrome 10。尽管如此,jQuery does not seem to be using it。我找到了一个关于它的bug report,但没有给出真正的解释?不过,我相信 jQuery 人有他们的理由。

他们为什么不使用这个很棒的 AP​​I?

【问题讨论】:

标签: jquery requestanimationframe


【解决方案1】:

ticket #9381 中,您可以了解他们为何在一段时间后停止使用requestionAnimationFrame

总而言之,问题是当窗口没有焦点时动画没有运行(浏览器试图减少 CPU 负载),如果窗口被隐藏,这是可以的,但如果它是可见的,就在外面重点。此外,动画队列堆积如山,在窗口重新获得焦点后,事情变得疯狂起来。这将需要对代码进行丑陋的更改和/或更改人们将内容添加到动画队列的方式。所以决定取消支持,直到有更好的方法来做到这一点。

【讨论】:

  • 从 jQuery 1.8 开始,我确保我们可以支持覆盖计时器循环,并编写了一个非常简单的插件,可以将 setInterval 替换为 requestAnimationFrame - github.com/gnarf37/jquery-requestAnimationFrame
  • 这主要是因为人们做了一些愚蠢的事情,比如setInterval(function{ $('.slideshow).animate(...); }, 3000);。相反,他们应该等待每个动画的结束来排队第二个。这是一个简单的解决方法,如果它着陆,我们都可以获得更流畅、更省电的动画。
【解决方案2】:

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

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 integrates requestAnimationFrame。基本上,jQuery 可以很好地处理它,但有些用户会打电话给.setInterval(function() { tag.animate(,把它搞砸了。因此,主要版本发布的平底船。 jQuery 3 不支持也永远不会支持 IE8 及以下版本,所以如果您有 IE8 用户,请坚持使用 jQuery 1.x。

CSS 过渡

在我的测试中,requestAnimationFrame 的 CPU/电池节省声明是虚假的承诺。我看到它的 CPU 使用率很高,例如,长时间褪色。节省 CPU/电池的是CSS Transitions,可能是因为浏览器,尤其是移动浏览器,会对您的意图和其他要求做出更强有力的假设,并且本机代码仍然比 Javascript+DOM 更快。

因此,如果您真的想节省 CPU/电池,CSS 过渡非常适合您。 IE9 及以下版本无法处理它们,并且仍然有大量用户,因此请考虑页面底部的jquery.transit 及其后备至animate

【讨论】:

  • 这是真的,当窗口没有焦点时,我可以看到滑块消失 - 至少在 Chrome 中。
【解决方案3】:

在 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,所以我不知道那个版本。如果它不在那个版本中,那么肯定有一些问题,所以它被删除了。

编辑:

如果您阅读this blog post,听起来它已从 1.6.3 中撤出,并且可能会在 1.7 中放回,它被撤出的主要原因是因为它破坏了人们“错误地”使用动画的一些东西排队等候(尽管这可能是一个见仁见智的问题)。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-05-08
  • 1970-01-01
  • 2016-09-22
  • 1970-01-01
  • 2019-10-20
  • 2016-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多