Search code examples
javascriptangularjssmooth-scrolling

angular-scroll not working...something missing?


I'm making a website using angular, and I want to be able to click on a specific element and make the page scroll down smoothly to a particular div. It's not working right now, and I'm not sure if I've missed something in my setup for this.

I've done bower install angular-scroll --save-dev which successfully added the angular-scroll folder to my bower_components, and the dependency to my bower.json file.

I've added the line <script src="bower_components/angular-scroll/angular-scroll.js"></script> to my index.html file.

And now the two relevant elements (the one I want to click and the one I want to scroll to) look like:

<a du-smooth-scroll="mainContent" du-scrollspy>Scroll down</a>
...
<div id="mainContent"> ... </div>

(I'm not using href="#mainContent" in my <a></a> tag because when I do, it seems to mess with my url, trying to add "mainContent" to the end of it)

Any ideas what might be going wrong?


Solution

  • Here is the working sample for what you want I believe :)

    var app = angular.module('plunker', []);
    app.controller('HeaderCtrl', function($scope) {
    });
    
    app.service('anchorSmoothScroll', function(){
        
        this.scrollTo = function(ID) {
    		// This scrolling function 
            // is from http://www.itnewb.com/tutorial/Creating-the-Smooth-Scroll-Effect-with-JavaScript
            var startY = currentYPosition();
            var stopY = elmYPosition(ID)-110; //value to set where is the end point to stop. Top margin 160px;
            var distance = stopY > startY ? stopY - startY : startY - stopY;
            if (distance < 100) {
                scrollTo(0, stopY); return;
            }
            var speed = Math.round(distance / 100);
            if (speed >= 20) speed = 20;
            var step = Math.round(distance / 100); //adjust the scrolling speed.
            var leapY = stopY > startY ? startY + step : startY - step;
            var timer = 0;
            if (stopY > startY) {
                for ( var i=startY; i<stopY; i+=step ) {
                    setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
                    leapY += step; if (leapY > stopY) leapY = stopY; timer++;
                } return;
            }
            for ( var i=startY; i>stopY; i-=step ) {
                setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
                leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
            }
            
            function currentYPosition() {
                // Firefox, Chrome, Opera, Safari
                if (self.pageYOffset) return self.pageYOffset;
                // Internet Explorer 6 - standards mode
                if (document.documentElement && document.documentElement.scrollTop)
                    return document.documentElement.scrollTop;
                // Internet Explorer 6, 7 and 8
                if (document.body.scrollTop) return document.body.scrollTop;
                return 0;
            }
            
            function elmYPosition(ID) {
                var elm = document.getElementById(ID);
                var y = elm.offsetTop;
                var node = elm;
                while (node.offsetParent && node.offsetParent != document.body) {
                    node = node.offsetParent;
                    y += node.offsetTop;
                } return y;
            }
    
        };
        
    });
    app.controller('ScrollCtrl', ['anchorSmoothScroll', '$location', '$scope',
      function (anchorSmoothScroll, $location, $scope) {
        $scope.gotoStep = function(x) {
          var newHash = 'step' + x;
          if ($location.hash() !== newHash) {
    		
    		 $location.hash('step' + x);
    		 anchorSmoothScroll.scrollTo('step' + x);
          } else {
            //$anchorScroll();
    		anchorSmoothScroll.scrollTo('step' + x);
          }
        };
    	
      }
    ]);
    /* Put your css in here */
    
    nav{
      position:fixed;
    }
    <!DOCTYPE html>
    <html  ng-app="plunker">
    
      <head>
        <meta charset="utf-8" />
        <title>AngularJS Plunker</title>
        <script>document.write('<base href="' + document.location + '" />');</script>
        <link rel="stylesheet" href="style.css" />
        <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
        <script src="app.js"></script>
      </head>
    
      <body>
       <nav class="navbar navbar-default sidebar" role="navigation" ng-controller="ScrollCtrl">
    			<div class="container-fluid">
    			<div class="collapse navbar-collapse">
    			  <ul class="nav navbar-nav">
    				<li id="doc1"><a href="" ng-click="gotoStep(1)"><span>one</span><span class="badge" style="float:right;">1</span></a></li>
    			 	<li id="doc2"><a href="" ng-click="gotoStep(2)"><span>two</span><span class="badge" style="float:right;">2</span></a></li>
    			  <li id="doc3"><a href="" ng-click="gotoStep(3)"><span>three</span><span class="badge" style="float:right;">3</span></a></li>
    			</ul>
    			</div>
    		  </div>
    		</nav>
    		<div id="step1" style="height:500px;background-color:red">
    		  <p>i am one</p>
    		</div>
    		<div id="step2" style="height:500px;background-color:green">
    		  <p>i am one</p>
    		</div>
    		<div id="step3" style="height:500px;background-color:blue">
    		  <p>i am one</p>
    		</div>
    		</body>
    
    </html>

    You can use directive for this too I have a solution for this as well. Please find the working snippet And Please Let me know if it was helpful.