I'm using a directive to fix my menu to the top of the page once my header scrolls past. I also would like my menu to use $anchorScroll to navigate to different elements of the page. The trouble I'm having is that the $anchorScroll goes past the anchor point unless you have scrolled past the header.
var myApp = angular.module('myApp', ['sticky']);
function IndexCtrl($scope, $location, $anchorScroll) {
$scope.gotoDiv = function (id) {
$scope.id = id;
$location.hash(id);
$anchorScroll();
}
}
angular.module('sticky', [])
.directive('sticky', [ function () {
return {
restrict: 'A',
link: function ($scope, $elem, $attrs) {
var offsetTop = 0,
$window = angular.element(window),
initialPositionStyle = $elem.css('position'),
stickyLine,
scrollTop;
// Set the top offset
$elem.css('top', '0');
$window.on('scroll', checkSticky);
setInitial();
function setInitial() {
stickyLine = $elem[0].offsetTop;
checkSticky();
}
function checkSticky() {
scrollTop = window.pageYOffset;
if (scrollTop >= stickyLine) {
$elem.css('position', 'fixed');
} else {
$elem.css('position', initialPositionStyle);
}
}
}
};
}]);
I created this plunker: http://plnkr.co/edit/7HfPtu4f1VoQ5vz4yVOJ?p=preview
-Click the menu the first time, the scroll goes to far. -A second click takes you the correct position. -scroll past the header, then click scroll goes to the correct position.
The header needs to be set to fixed before the scroll happens. like this:
var myApp = angular.module('myApp', ['sticky']);
function IndexCtrl($scope, $location, $anchorScroll) {
$scope.gotoDiv = function (id) {
$scope.stickyHeader();
$scope.id = id;
$location.hash(id);
$anchorScroll();
}
$scope.stickyHeader = function () {
service001.elem.css('position', 'fixed');
}
}
var service001 = {
}
angular.module('sticky', [])
.directive('sticky', [ function () {
return {
restrict: 'A',
link: function ($scope, $elem, $attrs) {
var offsetTop = 0,
$window = angular.element(window),
initialPositionStyle = $elem.css('position'),
stickyLine,
scrollTop;
// Set the top offset
$elem.css('top', '0');
$window.on('scroll', checkSticky);
setInitial();
service001.elem = $elem;
function setInitial() {
stickyLine = $elem[0].offsetTop;
checkSticky();
}
function checkSticky() {
scrollTop = window.pageYOffset;
if (scrollTop >= stickyLine) {
$elem.css('position', 'fixed');
} else {
$elem.css('position', initialPositionStyle);
}
}
}
};
}]);
There should be a service in here to share the elem.css position, but there it is.