Angular scroll directive

8.5k 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 answers

5
Pankaj Parkar 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
rcheuk 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;
}