-
-
Save monomial/d8f5797c05b8d3e1429a to your computer and use it in GitHub Desktop.
fork of EvilClosetMonkey's angularScrollSpy.js which is based on axhill's scrollspy.coffee. Closely mimics the Bootstrap ScrollSpy plugin in Angular.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Angular ScrollSpy directive | |
* | |
* When used with ngView / ngRoute, don't forget to set `reloadOnSearch` to false in the $routeProvider.when parameters | |
* https://docs.angularjs.org/api/ngRoute/provider/$routeProvider | |
* | |
* Use $anchorScroll.yOffset to provide an offset for a navigation bar at the top of the screen | |
*/ | |
(function ($) { | |
'use strict'; | |
angular.module("mjs.angularScrollSpy", []).directive('scrollSpy', [ | |
'$window', '$document', '$anchorScroll', function ($window, $document, $anchorScroll) { | |
return { | |
restrict: 'A', | |
controller: function ($scope) { | |
$scope.spies = []; | |
this.addSpy = function (spyObj) { | |
$scope.spies.push(spyObj); | |
}; | |
}, | |
link: function (scope, elem, attrs) { | |
var spyElems, // the elements being spied upon (jQuery objects) | |
$$window; | |
spyElems = []; | |
$$window = $($window); | |
scope.$watchCollection('spies', function (spies) { | |
var spy, i, spyCount; | |
spyCount = spies.length; | |
for (i = 0; i < spyCount; i++) { | |
spy = spies[i]; | |
if (spyElems[spy.id] == null) { | |
spyElems[spy.id] = elem.find('#' + spy.id); | |
} | |
} | |
}); | |
$$window.scroll(function () { | |
var highlightSpy, pos, spy, i, spyCount, scrollTopPlusOffset; | |
highlightSpy = null; | |
spyCount = scope.spies.length; | |
scrollTopPlusOffset = $$window.scrollTop() + $anchorScroll.yOffset; | |
// cycle through `spy` elements to find which to highlight | |
for (i = 0; i < spyCount; i++) { | |
spy = scope.spies[i]; | |
spy.deactivate(); | |
// catch case where a `spy` does not have an associated `id` anchor | |
if (spyElems[spy.id].offset() === undefined) { | |
continue; | |
} | |
if ((pos = spyElems[spy.id].offset().top) - scrollTopPlusOffset <= 0) { | |
// the window (plus offset) has been scrolled past the top of a spy element | |
spy.pos = pos; | |
if (highlightSpy == null || spy.pos > highlightSpy.pos) { | |
highlightSpy = spy; | |
} | |
} | |
} | |
// select the last `spy` if the scrollbar is at the bottom of the page | |
if ($$window.scrollTop() + $$window.height() >= $document.height()) { | |
spy.pos = pos; | |
highlightSpy = spy; | |
} | |
if (highlightSpy) { | |
highlightSpy.activate(); | |
} | |
}); | |
} | |
}; | |
}]).directive('spy', ['$location', '$anchorScroll', function ($location, $anchorScroll) { | |
return { | |
restrict: "A", | |
require: "^scrollSpy", | |
link: function (scope, elem, attrs, scrollSpy) { | |
elem.click(function () { | |
scope.$applyAsync(function () { | |
$location.hash(attrs.spy); | |
}); | |
}); | |
scrollSpy.addSpy({ | |
id: attrs.spy, | |
activate: function () { | |
elem.addClass('active'); | |
}, | |
deactivate: function () { | |
elem.removeClass('active'); | |
} | |
}); | |
} | |
}; | |
}]); | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment