【问题标题】:Changing css on scrolling Angular Style在滚动角度样式时更改 css
【发布时间】:2012-11-13 00:10:09
【问题描述】:

我想在用户滚动角度时更改 CSS 元素。

这是使用 JQuery 方式工作的代码

$(window).scroll(function() {
    if ($(window).scrollTop() > 20 && $(window).scrollTop() < 600) {
        $('header, h1, a, div, span, ul, li, nav').css('height','-=10px');
    } else if ($(window).scrollTop() < 80) {
        $('header, h1, a, div, span, ul, li, nav').css('height','100px');
    }

我尝试使用以下代码执行 Angular 方式,但 $scope.scroll 似乎无法正确获取滚动数据。

forestboneApp.controller('MainCtrl', function($scope, $document) {
    $scope.scroll = $($document).scroll();
    $scope.$watch('scroll', function (newValue) {
        console.log(newValue);
    });
});

【问题讨论】:

标签: angularjs


【解决方案1】:

请记住,在 Angular 中,DOM 访问应该发生在指令内。这是一个简单的指令,它根据窗口的scrollTop 设置一个变量。

app.directive('scrollPosition', function($window) {
  return {
    scope: {
      scroll: '=scrollPosition'
    },
    link: function(scope, element, attrs) {
      var windowEl = angular.element($window);
      var handler = function() {
        scope.scroll = windowEl.scrollTop();
      }
      windowEl.on('scroll', scope.$apply.bind(scope, handler));
      handler();
    }
  };
});

我不清楚您要寻找的最终结果是什么,所以这里有一个简单的演示应用程序,如果窗口向下滚动超过 50 像素,它会将元素的高度设置为 1pxhttp://jsfiddle.net/BinaryMuse/Z4VqP/

【讨论】:

  • 一个好的经验法则是,如果您可以直接计算和更改数据,请在控制器中进行 - 但如果您需要查询、操作或以其他方式访问 DOM,您可能应该使用一个指令。
  • @TomHart 我已经使用 AngularJS 1.2.8 重写了这个指令,以更好地支持写入范围(使用隔离范围,现在我们有真正的隔离范围),以及设置初始值一旦链接功能触发。
  • @BrandonTilley 你的小提琴是一颗宝石,谢谢。我从中学到了很多东西,我想给你一个拥抱。三个小问题:
    1. js,第 13 行:你为什么使用 'scope.$apply.bind(scope, handler)' 作为 handler fn?为什么不能简单地用 'handler' 代替(试过了,不起作用,但为什么?)?
    2. js,第 14 行:你为什么在这里调用处理程序 fn?我把它注释掉了,一切都很好。
    3. 如果我移除隔离范围,第 11 行 js 是否会将 windowEl.scrollTop() 的值分配给指令之外的 $scope.scroll?
  • @JaredTomaszewski 没问题! (1) 你必须 $apply 在 Angular 自己的函数之外异步发生的范围更改,以便脏跟踪系统获取更改。 (2) 如果指令链接时用户已经向下滚动;看这个例子:jsfiddle.net/BinaryMuse/V7GZ2 (3) 是的,它会,但是指令的可重用性较差,因为它只适用于名为scroll 的范围变量。
  • @JaredTomaszewski 是的,那是正确的——如果 Angular 还没有处于摘要周期中,那么您必须启动一个才能在视图中检测到范围的更改。 bind 只是普通的Function.prototype.bind;我只是创建了一个函数,它将调用scope.$apply 并将$scope 设置为this 上下文,并将handler 作为函数的第一个参数。你也可以说function() { scope.$apply(handler); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多