Skip to content

Commit 1c4d4a8

Browse files
committed
fix(browser): on first hash-set, dont set scrollTop
1 parent 59944db commit 1c4d4a8

File tree

6 files changed

+71
-12
lines changed

6 files changed

+71
-12
lines changed

js/ext/angular/src/ionicAngular.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ angular.module('ionic.service', [
1010
'ionic.service.modal',
1111
'ionic.service.popup',
1212
'ionic.service.templateLoad',
13-
'ionic.service.view'
13+
'ionic.service.view',
14+
'ionic.decorator.location'
1415
]);
1516

1617
// UI specific services and delegates
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
angular.module('ionic.decorator.location', [])
2+
3+
.config(['$provide', function($provide) {
4+
$provide.decorator('$location', ['$delegate', '$timeout', $LocationDecorator]);
5+
}]);
6+
7+
function $LocationDecorator($location, $timeout) {
8+
9+
var firstHashSet = false;
10+
$location.__hash = $location.hash;
11+
//Fix: first time window.location.hash is set, the scrollable area
12+
//found nearest to body's scrollTop is set to scroll to an element
13+
//with that ID.
14+
$location.hash = function(value) {
15+
if (!firstHashSet && angular.isDefined(value)) {
16+
$timeout(function() {
17+
var scroll = document.querySelector('.scroll-content');
18+
if (scroll)
19+
scroll.scrollTop = 0;
20+
}, 0, false);
21+
firstHashSet = true;
22+
}
23+
return $location.__hash(value);
24+
};
25+
26+
return $location;
27+
}

js/ext/angular/src/service/delegates/ionicScrollDelegate.js

+10-8
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,16 @@ angular.module('ionic.ui.service.scrollDelegate', [])
8181
});
8282

8383
$scope.$parent.$on('scroll.anchorScroll', function(e, animate) {
84-
var hash = $location.hash();
85-
var elm;
86-
if (hash && (elm = document.getElementById(hash)) ) {
87-
var scroll = ionic.DomUtil.getPositionInParent(elm, scrollEl);
88-
scrollView.scrollTo(scroll.left, scroll.top, !!animate);
89-
} else {
90-
scrollView.scrollTo(0,0, !!animate);
91-
}
84+
scrollViewResize().then(function() {
85+
var hash = $location.hash();
86+
var elm;
87+
if (hash && (elm = document.getElementById(hash)) ) {
88+
var scroll = ionic.DomUtil.getPositionInParent(elm, scrollEl);
89+
scrollView.scrollTo(scroll.left, scroll.top, !!animate);
90+
} else {
91+
scrollView.scrollTo(0,0, !!animate);
92+
}
93+
});
9294
});
9395

9496
/**

js/ext/angular/test/anchorScroll.html

+1-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@
5858
function MyCtrl($scope, $location, $ionicScrollDelegate) {
5959
$scope.scrollTo = function(id) {
6060
$location.hash(id);
61-
console.log($location.hash());
62-
$ionicScrollDelegate.anchorScroll();
61+
$ionicScrollDelegate.anchorScroll(true);
6362
}
6463
}
6564
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
describe('$location decorator', function() {
2+
3+
beforeEach(module('ionic.decorator.location'));
4+
5+
describe('.hash()', function() {
6+
7+
it('should find .scroll-content and set scrollTop=0', inject(function($location, $timeout, $rootScope) {
8+
var scroll = { scrollTop: 5 };
9+
spyOn(document, 'querySelector').andCallFake(function() {
10+
return scroll;
11+
});
12+
13+
$location.hash('123');
14+
$timeout.flush();
15+
expect(scroll.scrollTop).toBe(0);
16+
17+
//Second time? shouldnt try to set things
18+
scroll.scrollTop = 4;
19+
$location.hash('456');
20+
$timeout.verifyNoPendingTasks();
21+
expect(scroll.scrollTop).toBe(4);
22+
}));
23+
24+
});
25+
});

js/ext/angular/test/service/delegates/ionicScrollDelegate.unit.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,14 @@ describe('anchorScroll', function() {
9797

9898
function testWithAnimate(animate) {
9999
describe('with animate=' + animate, function() {
100-
var contentEl, scope, del;
100+
var contentEl, scope, del, timeout;
101101
beforeEach(inject(function($rootScope, $compile, $timeout, $document, $ionicScrollDelegate) {
102102
scope = $rootScope.$new();
103103
contentEl = $compile('<content></content>')(scope);
104104

105105
document.body.appendChild(contentEl[0]);
106106
del = $ionicScrollDelegate;
107+
timeout = $timeout;
107108
}));
108109

109110
it('should anchorScroll to an element with id', function() {
@@ -118,6 +119,7 @@ describe('anchorScroll', function() {
118119
contentEl.append(anchorMe);
119120

120121
del.anchorScroll(animate);
122+
timeout.flush();
121123
expect(sv.scrollTo).toHaveBeenCalledWith(2, 1, animate);
122124
});
123125

@@ -126,6 +128,8 @@ describe('anchorScroll', function() {
126128
spyOn(sv, 'scrollTo');
127129
spyOn(ionic.DomUtil, 'getPositionInParent');
128130
del.anchorScroll(animate);
131+
timeout.flush();
132+
129133
expect(sv.scrollTo).toHaveBeenCalledWith(0, 0, animate);
130134
expect(ionic.DomUtil.getPositionInParent).not.toHaveBeenCalled();
131135
});
@@ -137,6 +141,7 @@ describe('anchorScroll', function() {
137141

138142
setLocationHash('doesnotexist');
139143
del.anchorScroll(animate);
144+
timeout.flush();
140145

141146
expect(sv.scrollTo).toHaveBeenCalledWith(0, 0, animate);
142147
expect(ionic.DomUtil.getPositionInParent).not.toHaveBeenCalled();

0 commit comments

Comments
 (0)