Angular Scroll

by manland

HTML

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<div ng-app="app" ng-controller="ScrollController">
    <section class="column" >
        <ul>
          <li class="message" ng-repeat="m in messages" scroll="m">
              {{m.title}} - {{m.isView}}
          </li>
        </ul>
    </section>
    <input type="button" ng-click="addElements()" value="+" />
    <input type="button" ng-click="clear()" value="X" />
    <div ng-show="messagesNonVus() > 0">{{messagesNonVus()}} ⎙</div>
</div>

CSS

div {
    display: inline-block;  
    vertical-align: top;
    padding-top: 20px;
    padding-left: 20px;
}

.column {
    display: inline-block;
    overflow: auto;
    height: 200px;
    width: 200px;
}

.message {
    background-color: grey; 
    text-align:center;
    height: 40px;
    line-height: 40px;
    border-bottom: 1px solid black;
}

JavaScript

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

app.directive("scroll", ["$timeout", function($timeout) {
    
    var userScroll = false;
    
    return {
        restrict: 'A',
        link: function(scope, elmt, attrs)  {
            var element = elmt[0];
            var object = scope[attrs["scroll"]];
            object.isView = false;
            var scroller = angular.element(element.parentElement.parentElement); 
            
            var unwatch = scope.$watch(attrs["scroll"], function(newValue, oldValue) {
                if(object.isView == false) {
                    userScroll = false;
                    scroller[0].scrollTop += element.clientHeight;
                    $timeout(function() {
                        userScroll = true;
                    }, 0);
                }
            });
            
            var scrollMove = function(evt) {
                object.pos = element.offsetTop - scroller[0].offsetTop;
                if(evt.target.scrollTop <= object.pos && userScroll == true) {
                    object.isView = true;
                    scroller.unbind('scroll', scrollMove);
                    unwatch();
                    scope.$apply();
                }
            }
            scroller.bind('scroll', scrollMove); 
        }
    };
}]);

app.controller('ScrollController', ["$scope", "$rootScope", function($scope, $rootScope) {
    $scope.messages = [];
    
    for(var i=0; i<5; i++) {
        $scope.messages.splice(0, 0, {title:""+i});
    }
    
    $scope.addElements = function() {
        var size = $scope.messages.length;
        for(var i=size; i>-5-size; i--) {
            $scope.messages.splice(0, 0, {title:""+i});
        }
    }
    
    $scope.clear = function() {
        $scope.messages = [];
    }
    
    $scope.messagesNonVus = function() {
        var nb = 0;
        for(var i=0; i<$scope.messages.length; i++) {
            if($scope.messages[i].isView == false) {
                nb++;
            }
       ...