AngularJS - Smooth Anchor Scroll
by Premchand R
HTML
<div ng-app="app">
<div id="scrollArea" ng-controller="ScrollCtrl">
<a ng-click="gotoElement('middle')">Go to middle</a>
<br/>
<a ng-click="gotoElement('bottom')">Go to bottom</a>
<p>Keffiyeh locavore aesthetic trust fund. Fingerstache irony Truffaut gastropub, cliche chambray gentrify. PBR&B raw denim kogi, tote bag cardigan Tumblr Neutra readymade Odd Future vinyl. Small batch single-origin coffee swag selvage, Blue Bottle occupy
try-hard. Carles tote bag meggings Cosby sweater. Yr Vice photo booth put a bird on it, slow-carb kale chips locavore. Banh mi High Life biodiesel, Tonx fanny pack plaid Terry Richardson ennui small batch.</p>
<p>Single-origin coffee butcher next level, umami chia cornhole hashtag four loko PBR fashion axe sustainable. Church-key High Life sartorial butcher, hella +1 Intelligentsia chambray Wes Anderson Terry Richardson leggings Helvetica stumptown brunch
gentrify. Schlitz pour-over whatever cray, bicycle rights semiotics tousled try-hard hella selvage. Banksy next level art party, swag church-key Etsy bicycle rights hella synth hoodie Williamsburg Brooklyn letterpress meh stumptown. Slow-carb lo-fi
umami, 3 wolf moon vegan PBR banh mi pop-up. Semiotics kogi photo booth occupy next level mumblecore Banksy master cleanse, asymmetrical chia forage vinyl swag. Leggings beard shabby chic 3 wolf moon cray, farm-to-table skateboard you probably haven't
heard of them small batch squid mlkshk +1 banjo flannel pour-over.</p>
<p>Schlitz deep v hoodie pour-over banh mi. Helvetica yr Etsy Tumblr selvage. Tousled swag ennui Williamsburg disrupt PBR&B. VHS tattooed swag Terry Richardson, plaid bitters cred try-hard. Organic photo booth Neutra Pinterest. Banjo vinyl four loko
Neutra photo booth trust fund hella. Freegan retro Thundercats, locavore skateboard polaroid bicycle rights.</p>
<p>Marfa beard Echo Park, Thundercats jean shorts Truffaut Vice. Banjo roof party polaroid,...
CSS
#scrollArea {
height: 100%;
overflow: auto;
}
#bottom {
display: block;
}
JavaScript
var $scope, $location;
var app = angular.module('app', []);
app.service('anchorSmoothScroll', function() {
this.scrollTo = function(eID) {
// This scrolling function
// is from http://www.itnewb.com/tutorial/Creating-the-Smooth-Scroll-Effect-with-JavaScript
var startY = currentYPosition();
var stopY = elmYPosition(eID);
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 / 25);
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(eID) {
var elm = document.getElementById(eID);
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', function($scope, $location, anchorSmoothScroll) {
$scope.gotoElement =...