绑定类切换到窗口滚动事件

当用户在某个点以下滚动浏览器窗口时,我正在切换#page div的类。

我迄今所做的工作正常:

http://jsfiddle.net/eTTZj/29/

<div ng-app="myApp" scroll id="page"> <header></header> <section></section> </div> app = angular.module('myApp', []); app.directive("scroll", function ($window) { return function(scope, element, attrs) { angular.element($window).bind("scroll", function() { if (this.pageYOffset >= 100) { element.addClass('min'); console.log('Scrolled below header.'); } else { element.removeClass('min'); console.log('Header is in view.'); } }); }; }); 

(当他们滚动他们的窗口下面的标题,100px,类被切换)

虽然,纠正我,如果我错了,我觉得这是不是正确的方式来与Angular这样做。

相反,我推测这样做的最好方法是使用ng-class并在范围内存储一个布尔值。 像这样的东西:

 <div ng-app="myApp" scroll id="page" ng-class="{min: boolChangeClass}"> <header></header> <section></section> </div> app = angular.module('myApp', []); app.directive("scroll", function ($window) { return function(scope, element, attrs) { angular.element($window).bind("scroll", function() { if (this.pageYOffset >= 100) { scope.boolChangeClass = true; console.log('Scrolled below header.'); } else { scope.boolChangeClass = false; console.log('Header is in view.'); } }); }; }); 

虽然这不是dynamic的,但如果我在滚动callback中更改scope.boolChangeClass的值,那么ng-class不会更新。

所以我的问题是:当用户滚动到某个点以下时,最好是使用AngularJS切换#page的类。

感谢Flek在他的评论中回答我的问题:

http://jsfiddle.net/eTTZj/30/

 <div ng-app="myApp" scroll id="page" ng-class="{min:boolChangeClass}"> <header></header> <section></section> </div> app = angular.module('myApp', []); app.directive("scroll", function ($window) { return function(scope, element, attrs) { angular.element($window).bind("scroll", function() { if (this.pageYOffset >= 100) { scope.boolChangeClass = true; } else { scope.boolChangeClass = false; } scope.$apply(); }); }; }); 

为什么你们都build议重型作业? 我不明白为什么这不是一个“angular度”的解决scheme:

 .directive('changeClassOnScroll', function ($window) { return { restrict: 'A', scope: { offset: "@", scrollClass: "@" }, link: function(scope, element) { angular.element($window).bind("scroll", function() { if (this.pageYOffset >= parseInt(scope.offset)) { element.addClass(scope.scrollClass); } else { element.removeClass(scope.scrollClass); } }); } }; }) 

所以你可以像这样使用它:

 <navbar change-class-on-scroll offset="500" scroll-class="you-have-scrolled-down"></navbar> 

要么

 <div change-class-on-scroll offset="500" scroll-class="you-have-scrolled-down"></div> 

这是我的解决scheme,这不是那么棘手,并允许您通过一个简单的ng-class指令来使用它的几个标记。 像这样你可以select类和每个案例的scrollPos。

你的App.js:

 angular.module('myApp',[]) .controller('mainCtrl',function($window, $scope){ $scope.scrollPos = 0; $window.onscroll = function(){ $scope.scrollPos = document.body.scrollTop || document.documentElement.scrollTop || 0; $scope.$apply(); //or simply $scope.$digest(); }; }); 

您的index.html:

 <html ng-app="myApp"> <head></head> <body> <section ng-controller="mainCtrl"> <p class="red" ng-class="{fix:scrollPos >= 100}">fix me when scroll is equals to 100</p> <p class="blue" ng-class="{fix:scrollPos >= 150}">fix me when scroll is equals to 150</p> </section> </body> </html> 

在这里工作JSFiddle

编辑:

因为$apply()实际上是调用$rootScope.$digest()你可以直接使用$scope.$digest()而不是$scope.$apply()来取得更好的性能。
长话短说: $apply()将始终工作,但强制所有范围的$digest可能会导致性能问题。

也许这可以帮助:)

调节器

 $scope.scrollevent = function($e){ // Your code } 

HTML

 <div scroll scroll-event="scrollevent">//scrollable content</div> 

要么

 <body scroll scroll-event="scrollevent">//scrollable content</body> 

指示

 .directive("scroll", function ($window) { return { scope: { scrollEvent: '&' }, link : function(scope, element, attrs) { $("#"+attrs.id).scroll(function($e) { scope.scrollEvent != null ? scope.scrollEvent()($e) : null }) } } }) 

性能呢?

  1. 始终消除事件以减less计算
  2. 使用scope.applyAsync来减less整个摘要循环次数
 function debounce(func, wait) { var timeout; return function () { var context = this, args = arguments; var later = function () { timeout = null; func.apply(context, args); }; if (!timeout) func.apply(context, args); clearTimeout(timeout); timeout = setTimeout(later, wait); }; } angular.module('app.layout') .directive('classScroll', function ($window) { return { restrict: 'A', link: function (scope, element) { function toggle() { angular.element(element) .toggleClass('class-scroll--scrolled', window.pageYOffset > 0); scope.$applyAsync(); } angular.element($window) .on('scroll', debounce(toggle, 50)); toggle(); } }; }); 

3.如果你不需要触发观察者/摘要,那么使用compile

 .directive('classScroll', function ($window, utils) { return { restrict: 'A', compile: function (element, attributes) { function toggle() { angular.element(element) .toggleClass(attributes.classScroll, window.pageYOffset > 0); } angular.element($window) .on('scroll', utils.debounce(toggle, 50)); toggle(); } }; }); 

你可以像<header class-scroll="header--scrolled">一样使用它

指令并不像他们所说的那样是“在有棱的世界里面”。 所以当你改变东西的时候你必须使用apply来重新使用它