trigger
trigger

Reputation: 497

AngularJS How to watch offset top position of elements?

How to watch offset top position (of each element) and if the distance to top screen border lower than 100 px, i need to hide this div. (each div can move on page). Help please write Angular directive.

I can't watch each element top offset.

var app = angular.module('app', []);

app.app.directive('blah', function() {
  return {
    restrict: 'A',
    link: function(scope, element) {
      element.show();
      scope.$watch(function() {
        return element.offset().top > 120
      }, function(outOfBorder) {
        if (outOfBorder) {
          element.hide()
          console.log(outOfBorder)
        } else {
          element.show()
          console.log(outOfBorder)
        }
      });
    }
  }
});
.all {
height: 100px;
width: 300px;
 border:1px solid;
    overflow: scroll;
}
.elements {
height: 30px;
width: 300px;
 border:1px solid red;
float: left;
  clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div class="all" ng-app="app">
<div class="elements" blah></div>
<div class="elements" blah></div>
<div class="elements" blah></div>
<div class="elements" blah></div>
<div class="elements" blah></div>
<div class="elements" blah></div>
<div class="elements" blah></div>
<div class="elements" blah></div>
</div>

Upvotes: 1

Views: 6007

Answers (1)

BroiSatse
BroiSatse

Reputation: 44685

You simply add a watcher with a function (not tested + probably need some renaming):

angular.module('blah').directive('blah', function() {
  return {
    restrict: 'A',
    link: function(scope, element) {
      scope.$watch(function() {
        return element.offset().top < 100
      }, function(outOfBorder) {
        if (outOfBorder) {
          element.hide()
        } else {
          element.show()
        }
      });
    }
  }
});

The reason why your code is not working is that value you passed to a $watch is evaluated before $watch is executed. As a result, you watch top offset on the element at the time link is executed - this is a constant number.

EDIT:

If your elements are not absolutely positioned, calling hide will cause all the remaining elements to move up which eventually will make all elements hidden. In this case use element.addClass('invisible') and element.removeClass('invisible') instead of hiding and showing and define css class as:

.invisible { visibility: hidden; }

Changed visibility will not affect other element position.

Upvotes: 2

Related Questions