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?
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.