【问题标题】:AngularJS and getting window scroll position in controllerAngularJS并在控制器中获取窗口滚动位置
【发布时间】:2014-10-14 16:08:37
【问题描述】:

我在理解如何在我的控制器中获取窗口的滚动位置时遇到了一些麻烦,因此我可以围绕它构建逻辑。

从我一直在阅读的所有问题和答案中,最接受的答案似乎是编写一个计算滚动位置的指令,将该指令粘贴在一个元素上,就是这样。

但是,当您想按照以下方式做某事时:

if (scrollY > 100 ){
  $scope.showMenu = true;
}

if (scrollY > 500) {
  $scope.showFooter = true;
}

这种方法似乎不起作用,因为无法从控制器访问指令中的计算位置。这样做的正确“Angular”方式是什么,仍然允许从控制器执行稍微复杂的逻辑?

【问题讨论】:

标签: javascript angularjs scroll


【解决方案1】:

根据@RobKohr 评论,这是一种使用.on('scroll')$scope.$apply 更新滚动范围元素的优化方法。

$document.on('scroll', function() {
    // do your things like logging the Y-axis
    console.log($window.scrollY);

    // or pass this to the scope
    $scope.$apply(function() {
        $scope.pixelsScrolled = $window.scrollY;
    })
});

【讨论】:

  • 您将在滚动位置上获得更多粒度,因为它响应了本机滚动事件,但是每次处理程序触发时,您都会通过$applying 来调整角度范围。这绝对没有优化。相反,请参阅我对 RobKhor 的评论:requestAnimationFrame 是要走的路。不惜一切代价避免触摸示波器!
  • 据我记得,我的网站很多地方都需要我$scope.pixelsScrolled,这让我可以让它变得可维护,并且按照我的要求保持了良好的表现。
  • 但是,如果有人遇到性能问题,他仍然可以在我的 sn-p 上添加 console.log 的任何逻辑(如 RAF)。
【解决方案2】:

$window 服务注入您的控制器,它只是浏览器window 对象的一个​​包装器,并且您拥有$window.scrollX$window.scrollY 属性。

如果您想响应滚动的变化,请注意它们:

$scope.$watch(function () {
    return $window.scrollY;
}, function (scrollY) {
    /* logic */
});

【讨论】:

  • 为我工作。不过有点慢。好像不经常更新
  • @RobKohr 同意。该问题暗示在滚动位置更改时设置范围变量,因此$scope.$watch 最有意义,但我还应该提到requestAnimationFrame 应该用于这样的绘制操作。在这种情况下,对作用域变量的任何更改都应包含在 $scope.$apply 函数中,否则 Angular 将不会接收到它们 - 对于提高 requestAnimationFrame 的效率来说,这是一个小小的不便。
  • @SimonRobb 当我将$window.scrollY 与我的angular.element(...).prop('offsetTop') 进行比较时,它们完全不一致。当我在页面上向下滚动到元素时,$window.scrollY 显示 1552prop('offsetTop') 显示 2013,即使我已经到达该元素。如何让这些对齐?
【解决方案3】:

接受的答案缺少拆解代码:

错误(没有拆解)

$document.on('scroll', function() {
    // do your things like logging the Y-axis
    console.log($window.scrollY);

   // or pass this to the scope
    $scope.$apply(function() {
        $scope.pixelsScrolled = $window.scrollY;
    })
});

为避免内存泄漏和其他不良行为,代码需要在 $scope 被销毁时进行适当的拆卸。

$document.on('scroll', scrollHandler);

$scope.$on("$destroy", function() {
    $document.off('scroll', scrollHandler);
});

function scrollHandler(ev) {
    // do your things like logging the Y-axis
    console.log($window.scrollY);

    // or pass this to the scope
    $scope.$apply(function() {
        $scope.pixelsScrolled = $window.scrollY;
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-28
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多