Skip to content

Commit bda4de1

Browse files
committed
feat(scrolling): add native scroll delegate
1 parent 893fcbe commit bda4de1

File tree

13 files changed

+706
-258
lines changed

13 files changed

+706
-258
lines changed

config/build.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ module.exports = {
5555
// Views
5656
'js/views/view.js',
5757
'js/views/scrollView.js',
58+
'js/views/scrollViewNative.js',
5859
'js/views/listView.js',
5960
'js/views/modalView.js',
6061
'js/views/sideMenuView.js',

js/angular/controller/refresherController.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,8 @@ IonicModule
238238
scrollParent = $element.parent().parent()[0];
239239
scrollChild = $element.parent()[0];
240240

241-
if (!scrollParent.classList.contains('ionic-scroll') ||
242-
!scrollChild.classList.contains('scroll')) {
241+
if (!scrollParent || !scrollParent.classList.contains('ionic-scroll') ||
242+
!scrollChild || !scrollChild.classList.contains('scroll')) {
243243
throw new Error('Refresher must be immediate child of ion-content or ion-scroll');
244244
}
245245

js/angular/controller/scrollController.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,19 @@ function($scope,
2626
self.__timeout = $timeout;
2727

2828
self._scrollViewOptions = scrollViewOptions; //for testing
29+
self.isNative = function() {
30+
return !!scrollViewOptions.nativeScrolling;
31+
};
2932

3033
var element = self.element = scrollViewOptions.el;
3134
var $element = self.$element = jqLite(element);
32-
var scrollView = self.scrollView = new ionic.views.Scroll(scrollViewOptions);
35+
var scrollView;
36+
if (self.isNative()) {
37+
scrollView = self.scrollView = new ionic.views.ScrollNative(scrollViewOptions);
38+
} else {
39+
scrollView = self.scrollView = new ionic.views.Scroll(scrollViewOptions);
40+
}
41+
3342

3443
//Attach self to element as a controller so other directives can require this controller
3544
//through `require: '$ionicScroll'

js/angular/directive/content.js

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,37 +109,55 @@ function($timeout, $controller, $ionicBind, $ionicConfig) {
109109

110110
if ($attr.scroll === "false") {
111111
//do nothing
112-
} else if (attr.overflowScroll === "true" || !$ionicConfig.scrolling.jsScrolling()) {
113-
// use native scrolling
114-
$element.addClass('overflow-scroll');
115112
} else {
116-
var scrollViewOptions = {
117-
el: $element[0],
118-
delegateHandle: attr.delegateHandle,
119-
locking: (attr.locking || 'true') === 'true',
120-
bouncing: $scope.$eval($scope.hasBouncing),
121-
startX: $scope.$eval($scope.startX) || 0,
122-
startY: $scope.$eval($scope.startY) || 0,
123-
scrollbarX: $scope.$eval($scope.scrollbarX) !== false,
124-
scrollbarY: $scope.$eval($scope.scrollbarY) !== false,
125-
scrollingX: $scope.direction.indexOf('x') >= 0,
126-
scrollingY: $scope.direction.indexOf('y') >= 0,
127-
scrollEventInterval: parseInt($scope.scrollEventInterval, 10) || 10,
128-
scrollingComplete: function() {
129-
$scope.$onScrollComplete({
130-
scrollTop: this.__scrollTop,
131-
scrollLeft: this.__scrollLeft
132-
});
133-
}
134-
};
113+
var scrollViewOptions = {};
114+
115+
if (attr.overflowScroll === "true" || !$ionicConfig.scrolling.jsScrolling()) {
116+
// use native scrolling
117+
$element.addClass('overflow-scroll');
118+
119+
scrollViewOptions = {
120+
el: $element[0],
121+
delegateHandle: attr.delegateHandle,
122+
startX: $scope.$eval($scope.startX) || 0,
123+
startY: $scope.$eval($scope.startY) || 0,
124+
nativeScrolling:true
125+
};
126+
127+
} else {
128+
// Use JS scrolling
129+
scrollViewOptions = {
130+
el: $element[0],
131+
delegateHandle: attr.delegateHandle,
132+
locking: (attr.locking || 'true') === 'true',
133+
bouncing: $scope.$eval($scope.hasBouncing),
134+
startX: $scope.$eval($scope.startX) || 0,
135+
startY: $scope.$eval($scope.startY) || 0,
136+
scrollbarX: $scope.$eval($scope.scrollbarX) !== false,
137+
scrollbarY: $scope.$eval($scope.scrollbarY) !== false,
138+
scrollingX: $scope.direction.indexOf('x') >= 0,
139+
scrollingY: $scope.direction.indexOf('y') >= 0,
140+
scrollEventInterval: parseInt($scope.scrollEventInterval, 10) || 10,
141+
scrollingComplete: function() {
142+
$scope.$onScrollComplete({
143+
scrollTop: this.__scrollTop,
144+
scrollLeft: this.__scrollLeft
145+
});
146+
}
147+
};
148+
}
149+
150+
// init scroll controller with appropriate options
135151
$controller('$ionicScroll', {
136152
$scope: $scope,
137153
scrollViewOptions: scrollViewOptions
138154
});
139155

140156
$scope.$on('$destroy', function() {
141-
scrollViewOptions.scrollingComplete = noop;
142-
delete scrollViewOptions.el;
157+
if (scrollViewOptions) {
158+
scrollViewOptions.scrollingComplete = noop;
159+
delete scrollViewOptions.el;
160+
}
143161
innerElement = null;
144162
$element = null;
145163
attr.$$element = null;

js/angular/directive/infiniteScroll.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,14 @@ IonicModule
7979
link: function($scope, $element, $attrs, ctrls) {
8080
var infiniteScrollCtrl = ctrls[1];
8181
var scrollCtrl = infiniteScrollCtrl.scrollCtrl = ctrls[0];
82-
var jsScrolling = infiniteScrollCtrl.jsScrolling = !!scrollCtrl;
82+
var jsScrolling = infiniteScrollCtrl.jsScrolling = !scrollCtrl.isNative();
83+
8384
// if this view is not beneath a scrollCtrl, it can't be injected, proceed w/ native scrolling
8485
if (jsScrolling) {
8586
infiniteScrollCtrl.scrollView = scrollCtrl.scrollView;
87+
$scope.scrollingType = 'js-scrolling';
88+
//bind to JS scroll events
89+
scrollCtrl.$element.on('scroll', infiniteScrollCtrl.checkBounds);
8690
} else {
8791
// grabbing the scrollable element, to determine dimensions, and current scroll pos
8892
var scrollEl = ionic.DomUtil.getParentOrSelfWithClass($element[0].parentNode,'overflow-scroll');
@@ -91,14 +95,10 @@ IonicModule
9195
if (!scrollEl) {
9296
throw 'Infinite scroll must be used inside a scrollable div';
9397
}
94-
}
95-
//bind to appropriate scroll event
96-
if (jsScrolling) {
97-
$scope.scrollingType = 'js-scrolling';
98-
scrollCtrl.$element.on('scroll', infiniteScrollCtrl.checkBounds);
99-
} else {
98+
//bind to native scroll events
10099
infiniteScrollCtrl.scrollEl.addEventListener('scroll', infiniteScrollCtrl.checkBounds);
101100
}
101+
102102
// Optionally check bounds on start after scrollView is fully rendered
103103
var doImmediateCheck = isDefined($attrs.immediateCheck) ? $scope.$eval($attrs.immediateCheck) : true;
104104
if (doImmediateCheck) {

js/angular/directive/refresher.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,11 @@ IonicModule
8787
// JS Scrolling uses the scroll controller
8888
var scrollCtrl = ctrls[0],
8989
refresherCtrl = ctrls[1];
90-
91-
if (!!scrollCtrl) {
90+
if (!scrollCtrl || scrollCtrl.isNative()) {
91+
// Kick off native scrolling
92+
refresherCtrl.init();
93+
} else {
9294
$element[0].classList.add('js-scrolling');
93-
9495
scrollCtrl._setRefresher(
9596
$scope,
9697
$element[0],
@@ -102,10 +103,6 @@ IonicModule
102103
scrollCtrl.scrollView.finishPullToRefresh();
103104
});
104105
});
105-
106-
} else {
107-
// Kick off native scrolling
108-
refresherCtrl.init();
109106
}
110107

111108
}

0 commit comments

Comments
 (0)