Skip to content

Instantly share code, notes, and snippets.

@ArunMichaelDsouza
Last active September 6, 2015 21:32
Show Gist options
  • Save ArunMichaelDsouza/a83c70f1b94f88519e67 to your computer and use it in GitHub Desktop.
Save ArunMichaelDsouza/a83c70f1b94f88519e67 to your computer and use it in GitHub Desktop.
oua.directive('affixMenu', ['$window', '$filter', '$timeout', function ($window, $filter, $timeout) {
"use strict";
return {
restrict:'A',
replace:false,
transclude:false,
link:function (scope, element) {
var moveableOffset = element.offset(),
moveableHeight = element.height();
// add the menu links and heading positions to scope
scope.menuLinks = element.find('.nav a');
scope.menuHeadingPositions = [];
scope.scrolling = true;
// for each menu link, cache its heading and position
// on the current page so we can scroll to it
angular.forEach(scope.menuLinks, function (val) {
var $menuItem = $(val),
heading = $menuItem.attr('href');
scope.menuHeadingPositions.push({
id:heading,
position:$(heading).offset().top
});
});
// bind a click event to every link on the menu
// filtering by its target href, adding active
// state and smooth scrolling to the heading
// position on the page
scope.menuLinks.bind('click', function (e) {
e.preventDefault();
scope.scrolling = false;
var menuHeading = $filter('filter')(
scope.menuHeadingPositions,
{
id:$(this).attr('href')
}
)[0];
scope.menuLinks.removeClass('active');
$(this).addClass('active');
$('html,body').animate({scrollTop:menuHeading.position - 10}, 800, 'swing', function () {
scope.scrolling = true;
});
});
// bind the scroll function, so when we scroll past the menu
// it sticks to the top
$($window).bind('scroll', scrollBind);
// moves the elements on the screen
// limiting the movement based on the size of the sidebar
function scrollBind() {
var windowYOffset = $window.pageYOffset,
elementBottom = moveableHeight + windowYOffset,
pageLimit = $('#page-main .container').height() + $('#page-main .container').offset().top;
if (windowYOffset > moveableOffset.top) {
if (elementBottom <= pageLimit) {
element.offset({
top:windowYOffset + 10
});
}
if (scope.scrolling) {
angular.forEach(scope.menuHeadingPositions, function (val) {
if (windowYOffset >= (val.position - 10)) {
scope.menuLinks.filter('[href="' + val.id + '"]').addClass('active');
scope.menuLinks.filter('[href!="' + val.id + '"]').removeClass('active');
}
});
}
} else {
element.offset(moveableOffset);
}
}
}
};
}]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment