Question

I want banner to hide when user scroll downs. I took reference from Bind class toggle to window scroll event

I wanted to update a property in scope which I can use later to hide a banner.

Here is the code I have written: Ref: http://jsfiddle.net/8gYV4/

app = angular.module('myApp', []);
app.directive('ttlscrollhide', ['$window', function($window){
  return {
    link: function($scope, iElm, iAttrs) {
      var height = iElm[0].offsetHeight;
      angular.element($window).bind("scroll", function() {
        console.log(this.pageYOffset);
        if (this.pageYOffset >= height) {
          $scope.banner.hide = false;
        }
      })
    }
  };
}]).controller('MyCtrl', ['$scope', function($scope) {
  $scope.banner = {};
  $scope.banner.src = "http://art.exhibition.touchtalent.com/ex-12_2.png";
  $scope.banner.title = "Oho";
  $scope.banner.hide = true;
  $scope.toggle = function() {
    if($scope.banner.hide == true) {
      $scope.banner.hide = false;
    } else {
      $scope.banner.hide = true;
    }
  }
}]);

<div ng-controller="MyCtrl">
    <div ttlscrollhide ng-show="banner.hide">
      <img ng-src="{{banner.src}}">
    </div>
    <button ng-click="toggle()">Toggle</button>
</div>
    <br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br>

but its not updating the $scope variable. Whereas when I click on toggle button its working fine.

Was it helpful?

Solution

app = angular.module('myApp', []);
app.directive('ttlscrollhide', ['$window', function ($window) {
    return {
        link: function ($scope, iElm, iAttrs) {
            var height = iElm[0].offsetHeight;
            angular.element($window).bind("scroll", function () {
                console.log('visible : %s < %s %s', this.pageYOffset, height, this.pageYOffset < height);
                $scope.$apply(function(){
                    $scope.banner.hide = this.pageYOffset < height;
                });
            })
        }
    };
}]).controller('MyCtrl', ['$scope', function ($scope) {
    $scope.banner = {};
    $scope.banner.src = "http://art.exhibition.touchtalent.com/ex-12_2.png";
    $scope.banner.title = "Oho";
    $scope.banner.hide = true;
    $scope.toggle = function () {
        if ($scope.banner.hide == true) {
            $scope.banner.hide = false;
        } else {
            $scope.banner.hide = true;
        }
    }
}]);
<script src="https://code.angularjs.org/1.0.2/angular.min.js"></script>
<div ng-app="myApp">
    <div ng-controller="MyCtrl">
        <div id="test-div" ttlscrollhide ng-show="banner.hide">
            <img ng-src="{{banner.src}}" height="250px">
        </div>
        <button ng-click="toggle()">Toggle</button>
    </div>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
</div>

Actually, you have 2 competing problems here :

  • First : As you haven't set a height to your image, if you log the height variable, you'll see that it outputs '19', which is a bit small for the image you're using.
  • Second : You are manipulating scope variables (banner.hide) from a directive and from an event listener callback, I think this is considered "outside" angular scope, thus you must use $apply to notify angular that you're changing the scope from outside.

Here is an updated fiddle that seems to work for me. Let me know if it's ok for you.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top