切换标签时,jQuery动画功能中断

时间:2017-03-20 09:14:44

标签: javascript jquery angularjs jquery-animate

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

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

打开website。刷新网站,同时在浏览器标签when you see the spinner in the tab中加载页面。

enter image description here
切换到浏览器中的另一个选项卡。如果它不会发生。再试一次。如果这样说,你很可能会看到这个:

enter image description here

你可能会说,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)

enter image description here

我的问题是,如何在网站上查看用户是否为active?或者,即使用户active上没有browser tab,我仍然可以执行该功能吗?

因为似乎没有人有一个芒果,我自己想了一个小的解决方法。但是,如果某人仍然可以解释为什么animation在切换标签时会中断,我很高兴。

解决方法非常简单,我只需添加此代码。

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

而不是:

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

3 个答案:

答案 0 :(得分:4)

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

你可以在plunkr的jQuery文件中的7137行看到这个。

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

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

要解决此问题,您需要将complete函数声明移到调用animate之上。

答案 1 :(得分:0)

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

请查看我找到的链接:

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

答案 2 :(得分:-1)

 $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 - 角度不兼容。