Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

still working my head around angularjs directives and am a bit confused why this isn't working.

namely, i want a directive that tracks its position relative to a target and sets a target hit boolean. i also want to reuse this directive on my page, with each directive tracking a unique target.

app.directive('trackPosition', [function() {
    return {
        restrict: 'A',
        scope: {
            target: "=target"
        },
        link: function(scope, elem, attrs) {
            var navtop = elem[0].offsetTop; 
            window.onscroll = function() {
                var elemTop = elem[0].offsetTop;
                    targetTop = document.getElementById(scope.target).getBoundingClientRect().top;
                    console.log(scope.title + ", " + elemTop + ", " + targetTop);

                (targetTop <= elemTop && (-1 * targetTop) <= elemTop) ? scope.trackedTargetHit = true : scope.trackedTargetHit = false;
                scope.$apply();
            }
        }
    }
}]);


portfolio.controller('CtrlOne', function($scope) {
    $scope.title = 'CtrlOne';
    $scope.target = 'TargetOne';
    $scope.trackedTargetHit = false;
});

portfolio.controller('CtrlTwo', function($scope) {
    $scope.title = 'CtrlTwo';
    $scope.target = 'TargetTwo';
    $scope.trackedTargetHit = false;
});

<div ng-controller="CtrlOne" >
    <section ng-class="{'white' : trackedTargetHit}" track-position target="target">
    </section>
</div>

<div ng-controller="CtrlTwo" >
    <section ng-class="{'white' : trackedTargetHit}" track-position target="target">
    </section>
</div>

this works fine with just one directive, but used twice it musses up. i know this has something to do with my misuse of scopes in the directive. but getting very confused about how to use correctly; any suggestions greatly appreciated. thanks.

share|improve this question
add comment

2 Answers

up vote 0 down vote accepted

You are using

 window.onscroll = function() {

which is a global event handler. It is getting overwritten by subsequent directive calls - you will only ever have one handler when you do it this way. If you are including jQuery (and maybe even if not, I don't know if jqLite handles this) you can change it to

 $(window).on('scroll', function() {

and it will automatically take care of the event having two event handlers.

share|improve this answer
    
ahh. makes sense. thank you. this works for me now. –  vesperae Apr 8 at 16:59
add comment

thanks to dave this is working now:

/* track position */
app.directive("trackPosition", function ($window) {
    return function(scope, elem, attrs) {
        angular.element($window).bind("scroll", function() {
            var elemTop = elem[0].offsetTop;
                targetTop = document.getElementById(scope.target).getBoundingClientRect().top;

            (targetTop <= elemTop && (-1 * targetTop) <= elemTop) ? scope.trackedTargetHit = true : scope.trackedTargetHit = false;
            scope.$apply();
        });
    };
});
share|improve this answer
    
no jQuery needed. –  vesperae Apr 8 at 17:02
add comment

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.