Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have the following directive:

angular.module('mymod').directive("hideOnScroll", function($animate, $document) {
    return function(scope, element, attrs) {
        $document.bind('scroll', function () {
            if ($document.scrollTop() > 80) {
                console.log("this is fired1")
                $animate.addClass(element, "fade");
            } else {
                console.log("this is fired2")
                $animate.removeClass(element, "fade");
            }
        });
    };
});

I have both "this is fired" messages in the log at some point

Plus, I have the following animation service:

angular.module('mymod').animation(".fade", function() {
    console.log("this is never fired3")

    return {
        addClass: function(element, className) {
            console.log("this is never fired4")
            //TweenMax.to(element, 1, {opacity: 0});
        },
        removeClass: function(element, className) {
            console.log("this is never fired5")
            //TweenMax.to(element, 1, {opacity: 1});
        }
    };
});

None of it's console messages is fired. at all (3, 4 and 5). I checked if it's added to the browser, it is. And I have ngAnimate as a dependency

This is the element:

<div hide-on-scroll>Hello</div>

Edit: I can see in chrome's element inspector that the div doesn't get the new class after '$animate.addClass(element, "fade")' is fired

What am I missing?

share|improve this question
up vote 2 down vote accepted

When event handlers attached manually by for example addEventListener() or by the jqLite/jQuery methods onand bind execute you need to manually trigger the digest loop to let Angular know that something has changed.

You can use $apply (like for example ng-click does internally):

$document.bind('scroll', function() {
  scope.$apply(function() {
    if ($document.scrollTop() > 80) {
      console.log("this is fired1");
      $animate.addClass(element, "fade");
    } else {
      console.log("this is fired2");
      $animate.removeClass(element, "fade");
    }
  });
});

Also note that when you attach event listeners to the document you should manually remove them when the scope is destroyed:

var onScroll = function() {
  scope.$apply(function() {
    if ($document.scrollTop() > 80) {
      console.log("this is fired1");
      $animate.addClass(element, "fade");
    } else {
      console.log("this is fired2");
      $animate.removeClass(element, "fade");
    }
  });
};

$document.bind('scroll', onScroll);

scope.$on('$destroy', function() {
  $document.unbind('scroll', onScroll);
});

Demo: http://plnkr.co/edit/wl0vujSnBcb24FHGQ4il?p=preview

share|improve this answer
    
Give this man a medal ^^ – Ben Diamant Feb 24 '15 at 22:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.