Skip to content

Instantly share code, notes, and snippets.

@ArunMichaelDsouza
Last active September 6, 2015 21:32

Revisions

  1. @tarciosaraiva tarciosaraiva revised this gist Jan 31, 2013. 1 changed file with 31 additions and 25 deletions.
    56 changes: 31 additions & 25 deletions angular-affix.js
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,12 @@
    oua.directive('affixMenu', ['$window', '$filter', '$timeout', function ($window, $filter, $timeout) {
    oua.directive('affixMenu', ['$window', '$filter', function ($window, $filter) {
    "use strict";

    return {
    restrict:'A',
    replace:false,
    transclude:false,
    link:function (scope, element) {
    var moveableOffset = element.offset(),
    moveableHeight = element.height();
    var moveableHeight = element.height();

    // add the menu links and heading positions to scope
    scope.menuLinks = element.find('.nav a');
    @@ -52,34 +51,41 @@ oua.directive('affixMenu', ['$window', '$filter', '$timeout', function ($window,

    // bind the scroll function, so when we scroll past the menu
    // it sticks to the top
    var page = $('#page-main');

    $($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);
    var scrollHeight = page.height() + page.offset().top,
    scrollTop = $window.pageYOffset,
    position = element.offset(),
    offsetBottom = 0,
    offsetTop = element.parent().offset().top,
    reset = 'affix affix-top affix-bottom',
    affix;

    affix = scope.unpin != null && (scrollTop + scope.unpin <= position.top) ?
    false : position.top + element.height() >= scrollHeight - offsetBottom ?
    'bottom' : scrollTop <= offsetTop ?
    'top' : false;

    if (!affix && scope.scrolling) {
    angular.forEach(scope.menuHeadingPositions, function (val) {
    if (scrollTop >= (val.position - 10)) {
    scope.menuLinks.filter('[href="' + val.id + '"]').addClass('active');
    scope.menuLinks.filter('[href!="' + val.id + '"]').removeClass('active');
    }
    });
    }

    if (scope.affixed === affix) return;

    scope.affixed = affix;
    scope.unpin = affix == 'bottom' ? position.top - scrollTop : null;

    element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''));
    }
    }
    };
  2. @tarciosaraiva tarciosaraiva revised this gist Jan 29, 2013. 1 changed file with 19 additions and 13 deletions.
    32 changes: 19 additions & 13 deletions angular-affix.js
    Original file line number Diff line number Diff line change
    @@ -6,12 +6,13 @@ oua.directive('affixMenu', ['$window', '$filter', '$timeout', function ($window,
    replace:false,
    transclude:false,
    link:function (scope, element) {
    var moveableOffset = element.offset();
    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.scrollEnabled = true;
    scope.scrolling = true;

    // for each menu link, cache its heading and position
    // on the current page so we can scroll to it
    @@ -32,7 +33,7 @@ oua.directive('affixMenu', ['$window', '$filter', '$timeout', function ($window,
    scope.menuLinks.bind('click', function (e) {
    e.preventDefault();

    scope.scrollEnabled = false;
    scope.scrolling = false;

    var menuHeading = $filter('filter')(
    scope.menuHeadingPositions,
    @@ -44,26 +45,32 @@ oua.directive('affixMenu', ['$window', '$filter', '$timeout', function ($window,
    scope.menuLinks.removeClass('active');
    $(this).addClass('active');

    $('html,body').animate({scrollTop:menuHeading.position - 10}, 400, 'linear', function() {
    scope.scrollEnabled = true;
    $('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', function () {
    var windowYOffset = $window.pageYOffset;
    $($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) {

    $timeout(function() {
    if (elementBottom <= pageLimit) {
    element.offset({
    top:windowYOffset + 10
    });
    }, 400);
    }

    if (scope.scrollEnabled) {
    angular.forEach(scope.menuHeadingPositions, function(val) {
    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');
    @@ -73,8 +80,7 @@ oua.directive('affixMenu', ['$window', '$filter', '$timeout', function ($window,
    } else {
    element.offset(moveableOffset);
    }
    });

    }
    }
    };
    }]);
  3. @tarciosaraiva tarciosaraiva revised this gist Jan 29, 2013. 1 changed file with 7 additions and 5 deletions.
    12 changes: 7 additions & 5 deletions angular-affix.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    oua.directive('affixMenu', ['$window', '$filter', function ($window, $filter) {
    oua.directive('affixMenu', ['$window', '$filter', '$timeout', function ($window, $filter, $timeout) {
    "use strict";

    return {
    @@ -44,7 +44,7 @@ oua.directive('affixMenu', ['$window', '$filter', function ($window, $filter) {
    scope.menuLinks.removeClass('active');
    $(this).addClass('active');

    $('html,body').animate({scrollTop:menuHeading.position - 10}, 600, 'linear', function() {
    $('html,body').animate({scrollTop:menuHeading.position - 10}, 400, 'linear', function() {
    scope.scrollEnabled = true;
    });
    });
    @@ -56,9 +56,11 @@ oua.directive('affixMenu', ['$window', '$filter', function ($window, $filter) {

    if (windowYOffset > moveableOffset.top) {

    element.offset({
    top:windowYOffset + 10
    });
    $timeout(function() {
    element.offset({
    top:windowYOffset + 10
    });
    }, 400);

    if (scope.scrollEnabled) {
    angular.forEach(scope.menuHeadingPositions, function(val) {
  4. @tarciosaraiva tarciosaraiva created this gist Jan 29, 2013.
    78 changes: 78 additions & 0 deletions angular-affix.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    oua.directive('affixMenu', ['$window', '$filter', function ($window, $filter) {
    "use strict";

    return {
    restrict:'A',
    replace:false,
    transclude:false,
    link:function (scope, element) {
    var moveableOffset = element.offset();

    // add the menu links and heading positions to scope
    scope.menuLinks = element.find('.nav a');
    scope.menuHeadingPositions = [];
    scope.scrollEnabled = 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.scrollEnabled = 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}, 600, 'linear', function() {
    scope.scrollEnabled = true;
    });
    });

    // bind the scroll function, so when we scroll past the menu
    // it sticks to the top
    $($window).bind('scroll', function () {
    var windowYOffset = $window.pageYOffset;

    if (windowYOffset > moveableOffset.top) {

    element.offset({
    top:windowYOffset + 10
    });

    if (scope.scrollEnabled) {
    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);
    }
    });

    }
    };
    }]);