3

我不确定这个问题的正确标题是什么,所以如果我错了,请纠正我。

假设在页面刷新(加载)时,我需要根据当前位置的哈希值执行动画滚动以锚定(我知道 ngAnchorScroll,但我需要一个动画 scolling,而 ngAnchorScorll 无法做到)。

为此,我实现了一个服务,它将在控制器初始化时调用:

var Ctrl = function ($scope, initAnchorScrolling) {
    initAnchorScrolling($scope);
};

Ctrl.$inject = ['$scope', "initAnchorScrolling"];

applicationServices.factory("initAnchorScrolling",
    ['scroll', '$location', '$timeout', function(scrollUtils, $location, $timeout) {
    return function(scope) {

    /** Some stuff here */

    function scroll() {
        var hash = $location.hash(), elm;

        if (!hash) {
            scrollUtils.scrollTo(0, 0);
        } else if ((elm = getAnchorElement(hash))) {
            scrollUtils.scrollToElement(elm);
        } else {
            scrollUtils.scrollTo(0, 0);
        }
    }

    scope.$watch(function scrollWatch() { return $location.hash(); },
        function scrollWatchAction() {
            $timeout(function () {
                scroll();
            }, 0, true);
        });
    };
}]);

您可能会看到锚点的实现与 ngAnchorScroll 的实现非常相似。主要区别在于我使用 jQuery.animate() 在锚点之间移动。

正如我从这里理解的那样,将函数执行推迟到那一刻,当浏览器完成渲染时,我们只需要使用延迟参数调用 $timeout 服务,该参数等于 0。但这对我不起作用。偶尔页面滚动到不同的位置。我可以这样解释——在摘要循环完成视图和模型的同步之前调用滚动函数,因此在调用时 HTML 块的高度和位置无效。

所以我的问题是:是否可以将函数调用推迟到浏览器完全完成渲染并且摘要周期完成视图和模型的同步(应用绑定)的那一刻?

4

1 回答 1

0

最初的问题是关于滚动到特定的哈希,而这个解决方案是关于无论如何保留滚动位置。它仍然可以为您提供解决方案

我创建了一个适用于窗口滚动的指令(它可以更新为适用于任何元素)

html用法

<div ng-keep-scroll="service.scrollY">
<!-- list of scrolling things here -->
</div>

其中“service.scrollY”必须是服务中的变量。服务保留它们的状态和值,每次加载和清除它们的值时都会重新创建控制器,因此您不能使用它们来存储持久数据。控制器有一个指向服务的范围变量。

指令js

app.directive('ngKeepScroll', function ($timeout) {
    return function (scope, element, attrs) {

        //load scroll position after everything has rendered
        $timeout(function () {
            var scrollY = parseInt(scope.$eval(attrs.ngKeepScroll));
            $(window).scrollTop(scrollY ? scrollY : 0);
        }, 0);

        //save scroll position on change
        scope.$on("$routeChangeStart", function () {
            scope.$eval(attrs.ngKeepScroll + " = " + $(window).scrollTop());
        });
    }
});
于 2013-05-13T02:53:29.637 回答