【问题标题】:jQuery animation function breaks when switching tabs切换标签时jQuery动画功能中断
【发布时间】:2017-03-20 09:14:43
【问题描述】:

更新:我在 plunkr 中重现了错误:请参阅 http://plnkr.co/BpYfCNBESUT6ZkiSZHgx

当您执行以下操作时会出现问题:

打开website。刷新网站,当您在浏览器选项卡中看到页面正在加载时,when you see the spinner in the tab


切换到浏览器中的另一个选项卡。如果没有发生。再试一次。如果按照上述方式进行操作,您很可能会看到以下内容:

你可能会说,this is not such a big deal, you have to be real fast to let this error happen。但是,想象一下某个连接速度较慢的人,他转到浏览器中的另一个选项卡,继续观看他的 youtube 视频,同时网站正在加载。当他回来时,他只是看到页面一直在加载。


让我们说这个animation代码:

$pageloaderbar.animate({
    width: "46%"
}, {
    duration: 700,
    complete: function () {
        $scope.continue();
    }
});

当第一个animation 完成时,它会调用一个名为$scope.continue(); 的新函数。看起来像这样:

$scope.continue = function () {
    $timeout(function () {
        $pageloaderbar.animate({
            width: "100%"
        }, {
            duration: 500,
            complete: function () {
                $scope.PageIsLoading = false;
            }
        });
    });
}

问题是,当用户在浏览器中切换选项卡时,在$pageloaderbar.animate$scope.continue 之间切换时,$plageloaderbar.animate 函数永远不会到达complete 函数。浏览器控制台显示以下错误(Chrome)

我的问题是,我如何查看网站上的用户是否为active?或者,即使browser tab 上的用户不是active,我如何仍能执行该功能?

因为似乎没有人有遮阳篷,所以我自己想出了一个小解决方法。但是,如果有人仍然可以解释为什么切换标签时animation 会中断,我非常高兴。

解决方法很简单,我只需要添加这段代码。

complete: function () {
    if(document.hidden) {
        $(window).on("blur focus", function () {
            $scope.continue();
        });
    } else {
        $scope.continue();
    }
}

代替:

complete: function () {
    $scope.continue();
}

【问题讨论】:

  • 你能用 plunker/fiddle 重现这个吗?
  • 对不起,在 sn-p 中它工作得很好。我也无法在本地开发环境中展示演示。
  • 什么是$scope,为什么当前标签有焦点时没有定义它?你有没有追踪过它? $scope 的生命周期中发生了什么?我们无法从您提供的内容中看到很多内容,但这不应该以这种方式做出反应。 Console.log($scope) 在不同的地方,看看你发现了什么。
  • 你能在这里添加相关代码吗?我认为$scope.continue 已被覆盖。可能是布尔值$scope.continue = false;。这就是为什么当你调用$scope.continue() 时,它会抛出错误... is not a function
  • @trevster344 $scope 来自angular 如果您有兴趣,这里是整个代码。也许对你有帮助:jsfiddle.net/3kc32zf3

标签: javascript jquery angularjs jquery-animate


【解决方案1】:

这是由 jQuery animate 函数引起的,该函数将动画选项对象传递给名为 speed 的函数。此函数检查document 是否为hidden - 如果选项卡处于非活动状态,则为hidden。如果隐藏,(或fx.off设置为true),所有动画时长设置为0

您可以在 plunkr 的 jQuery 文件中的 7137 行看到此内容。

    if ( jQuery.fx.off || document.hidden ) {
    opt.duration = 0;

由于动画现在没有持续时间,它变得同步,因此您的complete 函数在调用animate 之后出现,这是一个问题。

要解决此问题,您需要将调用上方的 complete 函数声明移至 animate

【讨论】:

  • 你应该得到赏金,你确实仔细研究了代码并弄明白了。我查了一下,这是真的。当你把它放在上面时它会起作用,而且 jquery 也会中断,因为它设置了opt.duration = 0。 Ñ干得好!
【解决方案2】:

在较新版本的 chrome 中,这与选项卡的可见性有关,因此您的功能会中断。您可以使用可见性 API 来了解该选项卡对用户是否可见。

请看一下我找到的这个链接:

http://dystroy.org/demos/vis-en.html

【讨论】:

  • 好吧,如果您仔细阅读我的问题,您会发现我实际上必须添加它才能使代码正常工作。它与可见性 API 无关。刚刚阅读问题,问题是来自jQuery api 的animation 函数,它在切换标签时中断..
【解决方案3】:
 $scope.continue = function () {
        $timeout(function () {
            $pageloaderbar.animate({
                width: "100%"
            }, {
                duration: 500,
                complete: function () {
                    $scope.PageIsLoading = false;

                    $("body").css("overflow", "auto");
                    $pageloaderwrap.addClass("page-loader-finished");

                    $scope.pageReady();
                }
            });
        });
    }

    var $pageloaderwrap = $(".page-loader-wrap");
    var $pageloader = $(".page-loader");
    var $pageloaderbar = $(".page-loader .page-loader-bar");

    $("body").css("overflow", "hidden");


    $pageloaderbar.animate({
        width: "46%"
    }, {
        duration: 700,
        complete: function () {
            if (document.hidden) {
                $(window).on("blur focus", function () {
                    $scope.continue();
                });
            } else {
                $scope.continue();
            }
        }
    });

尝试在调用 $pageloaderbar.animate 之前定义您的 continue 函数。这可能不是主要问题,但总有可能因此而出现问题。

您的解决方案只是一个补丁,不是真正的解决方案,而且看起来不太好。即使它解决了你的问题,你也必须找到某种方法来防止这个错误。

我强烈建议你离开 jquery。此类问题通常来自 jquery - 角度不兼容。

【讨论】:

  • 这不是遮阳篷。发表评论之类的东西。我知道,由于声誉,您不能发布 cmets。请记住发布遮阳篷,而不是提示和诸如“可能是因为这个”之类的内容
猜你喜欢
  • 2014-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 2012-03-11
  • 2010-10-30
  • 2013-02-12
  • 1970-01-01
相关资源
最近更新 更多