Bind class toggle to window scroll event
Solution 1:
Thanks to Flek for answering my question in his comment:
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();
});
};
});
Solution 2:
Why do you all suggest heavy scope operations? I don't see why this is not an "angular" solution:
.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);
}
});
}
};
})
So you can use it like this:
<navbar change-class-on-scroll offset="500" scroll-class="you-have-scrolled-down"></navbar>
or
<div change-class-on-scroll offset="500" scroll-class="you-have-scrolled-down"></div>
Solution 3:
This is my solution, it's not that tricky and allow you to use it for several markup throught a simple ng-class directive. Like so you can choose the class and the scrollPos for each case.
Your 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();
};
});
Your 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>
working JSFiddle here
EDIT :
As
$apply()
is actually calling$rootScope.$digest()
you can directly use$scope.$digest()
instead of$scope.$apply()
for better performance depending on context.
Long story short :$apply()
will always work but force the$digest
on all scopes that may cause perfomance issue.
Solution 4:
Maybe this can help :)
Controller
$scope.scrollevent = function($e){
// Your code
}
Html
<div scroll scroll-event="scrollevent">//scrollable content</div>
Or
<body scroll scroll-event="scrollevent">//scrollable content</body>
Directive
.directive("scroll", function ($window) {
return {
scope: {
scrollEvent: '&'
},
link : function(scope, element, attrs) {
$("#"+attrs.id).scroll(function($e) { scope.scrollEvent != null ? scope.scrollEvent()($e) : null })
}
}
})