Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

feat($anchorScroll): allow scrolling to a specified element #9596

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions src/ng/anchorScroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ function $AnchorScrollProvider() {
* @requires $rootScope
*
* @description
* When called, it checks the current value of {@link ng.$location#hash $location.hash()} and
* scrolls to the related element, according to the rules specified in the
* [Html5 spec](http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document).
* When called, it scrolls to the element related to the specified `hash` or (if omitted) to the
* current value of {@link ng.$location#hash $location.hash()}, according to the rules specified
* in the
* [HTML5 spec](http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document).
*
* It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to
* match any anchor whenever it changes. This can be disabled by calling
Expand All @@ -49,6 +50,9 @@ function $AnchorScrollProvider() {
* Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a
* vertical scroll-offset (either fixed or dynamic).
*
* @param {string=} hash The hash specifying the element to scroll to. If omitted, the value of
* {@link ng.$location#hash $location.hash()} will be used.
*
* @property {(number|function|jqLite)} yOffset
* If set, specifies a vertical scroll-offset. This is often useful when there are fixed
* positioned elements at the top of the page, such as navbars, headers etc.
Expand Down Expand Up @@ -232,8 +236,9 @@ function $AnchorScrollProvider() {
}
}

function scroll() {
var hash = $location.hash(), elm;
function scroll(hash) {
hash = isString(hash) ? hash : $location.hash();
var elm;

// empty hash, scroll to the top of the page
if (!hash) scrollTo(null);
Expand Down
135 changes: 102 additions & 33 deletions test/ng/anchorScrollSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ describe('$anchorScroll', function() {
};
}


function addElements() {
var elements = sliceArgs(arguments);

Expand All @@ -49,9 +48,9 @@ describe('$anchorScroll', function() {
};
}

function callAnchorScroll() {
function callAnchorScroll(hash) {
return function($anchorScroll) {
$anchorScroll();
$anchorScroll(hash);
};
}

Expand Down Expand Up @@ -141,50 +140,120 @@ describe('$anchorScroll', function() {
beforeEach(createMockWindow());


it('should scroll to top of the window if empty hash', inject(
changeHashAndScroll(''),
expectScrollingToTop));
describe('and implicitly using `$location.hash()`', function() {

it('should scroll to top of the window if empty hash', inject(
changeHashAndScroll(''),
expectScrollingToTop));


it('should not scroll if hash does not match any element', inject(
addElements('id=one', 'id=two'),
changeHashAndScroll('non-existing'),
expectNoScrolling()));


it('should scroll to anchor element with name', inject(
addElements('a name=abc'),
changeHashAndScroll('abc'),
expectScrollingTo('a name=abc')));


it('should not scroll to other than anchor element with name', inject(
addElements('input name=xxl', 'select name=xxl', 'form name=xxl'),
changeHashAndScroll('xxl'),
expectNoScrolling()));


it('should scroll to anchor even if other element with given name exist', inject(
addElements('input name=some', 'a name=some'),
changeHashAndScroll('some'),
expectScrollingTo('a name=some')));


it('should scroll to element with id with precedence over name', inject(
addElements('name=abc', 'id=abc'),
changeHashAndScroll('abc'),
expectScrollingTo('id=abc')));


it('should not scroll if hash does not match any element', inject(
addElements('id=one', 'id=two'),
changeHashAndScroll('non-existing'),
expectNoScrolling()));
it('should scroll to top if hash == "top" and no matching element', inject(
changeHashAndScroll('top'),
expectScrollingToTop));


it('should scroll to anchor element with name', inject(
addElements('a name=abc'),
changeHashAndScroll('abc'),
expectScrollingTo('a name=abc')));
it('should scroll to element with id "top" if present', inject(
addElements('id=top'),
changeHashAndScroll('top'),
expectScrollingTo('id=top')));
});


describe('and specifying a hash', function() {

it('should ignore the `hash` argument if not a string', inject(
spyOnJQLiteDocumentLoaded(),
addElements('id=one', 'id=two'),
changeHashTo('one'), // won't scroll since `jqLiteDocumentLoaded()` is spied upon
callAnchorScroll({}),
expectScrollingTo('id=one'),
unspyOnJQLiteDocumentLoaded()));


it('should ignore `$location.hash()` if `hash` is passed as argument', inject(
spyOnJQLiteDocumentLoaded(),
addElements('id=one', 'id=two'),
changeHashTo('one'), // won't scroll since `jqLiteDocumentLoaded()` is spied upon
callAnchorScroll('two'),
expectScrollingTo('id=two'),
unspyOnJQLiteDocumentLoaded()));


it('should scroll to top of the window if empty hash', inject(
callAnchorScroll(''),
expectScrollingToTop));

it('should not scroll to other than anchor element with name', inject(
addElements('input name=xxl', 'select name=xxl', 'form name=xxl'),
changeHashAndScroll('xxl'),
expectNoScrolling()));

it('should not scroll if hash does not match any element', inject(
addElements('id=one', 'id=two'),
callAnchorScroll('non-existing'),
expectNoScrolling()));

it('should scroll to anchor even if other element with given name exist', inject(
addElements('input name=some', 'a name=some'),
changeHashAndScroll('some'),
expectScrollingTo('a name=some')));

it('should scroll to anchor element with name', inject(
addElements('a name=abc'),
callAnchorScroll('abc'),
expectScrollingTo('a name=abc')));

it('should scroll to element with id with precedence over name', inject(
addElements('name=abc', 'id=abc'),
changeHashAndScroll('abc'),
expectScrollingTo('id=abc')));

it('should not scroll to other than anchor element with name', inject(
addElements('input name=xxl', 'select name=xxl', 'form name=xxl'),
callAnchorScroll('xxl'),
expectNoScrolling()));

it('should scroll to top if hash == "top" and no matching element', inject(
changeHashAndScroll('top'),
expectScrollingToTop));

it('should scroll to anchor even if other element with given name exist', inject(
addElements('input name=some', 'a name=some'),
callAnchorScroll('some'),
expectScrollingTo('a name=some')));

it('should scroll to element with id "top" if present', inject(
addElements('id=top'),
changeHashAndScroll('top'),
expectScrollingTo('id=top')));

it('should scroll to element with id with precedence over name', inject(
addElements('name=abc', 'id=abc'),
callAnchorScroll('abc'),
expectScrollingTo('id=abc')));


it('should scroll to top if hash == "top" and no matching element', inject(
callAnchorScroll('top'),
expectScrollingToTop));


it('should scroll to element with id "top" if present', inject(
addElements('id=top'),
callAnchorScroll('top'),
expectScrollingTo('id=top')));
});
});


Expand Down