Angular scroll directive

8.4k Views Asked by At

I try to create a directive with two params, class and pageYOffset. I would like to check the scrolling position of my element and add a class name if the pageYOffset is bigger than the number in the attr. Somehow I cant't trigger the class changes.

HTML

<div scroll offset="1500" ng-class="{active : scrollClass}"></div>

Directive

app.directive('scroll', function($window) {
    return {
        scope: {
          offset: "@offset"
        },
        link: function (scope, element, attr) {
            angular.element($window).bind("scroll", function() {
                if (this.pageYOffset >= scope.offset) {
                    scope.scrollClass = true;
                }
                scope.$apply();
            });
        }
    }
});
2

There are 2 best solutions below

5
On BEST ANSWER

As you are using isolated class, your directive scope is different scope than you controller scope, controller scope will not get inherited to directive scope because scope: {..}, As you want to change flag of parent scope you need to pass that value inside your directive with = which will perform two way binding as inner scope variable change will affect to the parent scope variable value.

Makrup

<div scroll offset="1500" scroll-class="scrollClass" ng-class="{active : scrollClass}"></div>

Directive

app.directive('scroll', function($window) {
    return {
        scope: {
          offset: "@offset",
          scrollClass: '='
        },
        link: function (scope, element, attr) {
            angular.element($window).bind("scroll", function(event) {
                if (element.pageYOffset >= scope.offset) {
                    //this will change the parent scope variable value to true
                    scope.scrollClass = true;
                }
                scope.$apply(); //need full to run digest cycle
            });
        }
    }
});
0
On

You can try something like tihs:

app.directive('scroll', function($window) {
    return {
        scope: {
          offset: "@offset",
          toggleScroll: "&toggle"
        },
        link: function (scope, element, attr) {
            angular.element($window).bind("scroll", function() {
                if (this.pageYOffset >= scope.offset) {
                    toggle();
                }
                //scope.$apply();
            });
        }
    }
});

<div scroll offset="1500" toggle-scroll="changeActiveClass()" ng-class="{active : scrollClass}"></div>

Then define changeActiveClass in your parent scope:

$scope.changeActiveClass = function() {
    $scope.scrollClass = !scrollClass;
}