Skip to content

Commit fe3aeac

Browse files
committed
feat(menu): better scroll restrict. Fixes #4869
1 parent 1ec38ac commit fe3aeac

File tree

9 files changed

+84
-7
lines changed

9 files changed

+84
-7
lines changed

Diff for: js/angular/controller/scrollController.js

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ function($scope,
184184
};
185185

186186
self.freezeScroll = scrollView.freeze;
187+
self.freezeScrollShut = scrollView.freezeShut;
187188

188189
self.freezeAllScrolls = function(shouldFreeze) {
189190
for (var i = 0; i < $ionicScrollDelegate._instances.length; i++) {

Diff for: js/angular/controller/sideMenuController.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,10 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
157157
// equal 0, otherwise remove the class from the body element
158158
$ionicBody.enableClass((percentage !== 0), 'menu-open');
159159

160-
freezeAllScrolls(false);
160+
self.content.setCanScroll(percentage == 0);
161161
};
162162

163+
/*
163164
function freezeAllScrolls(shouldFreeze) {
164165
if (shouldFreeze && !self.isScrollFreeze) {
165166
$ionicScrollDelegate.freezeAllScrolls(shouldFreeze);
@@ -169,6 +170,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
169170
}
170171
self.isScrollFreeze = shouldFreeze;
171172
}
173+
*/
172174

173175
/**
174176
* Open the menu the given pixel amount.
@@ -320,8 +322,6 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
320322

321323
// End a drag with the given event
322324
self._endDrag = function(e) {
323-
freezeAllScrolls(false);
324-
325325
if (isAsideExposed) return;
326326

327327
if (isDragging) {
@@ -359,7 +359,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
359359

360360
if (isDragging) {
361361
self.openAmount(offsetX + (lastX - startX));
362-
freezeAllScrolls(true);
362+
self.content.setCanScroll(false);
363363
}
364364
};
365365

@@ -443,7 +443,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
443443
}
444444

445445
// ensure scrolls are unfrozen
446-
freezeAllScrolls(false);
446+
self.content.setCanScroll(true);
447447
});
448448

449449
self.initialize({

Diff for: js/angular/directive/content.js

+2
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ function($timeout, $controller, $ionicBind, $ionicConfig) {
159159
scrollViewOptions: scrollViewOptions
160160
});
161161

162+
$scope.scrollCtrl = scrollCtrl;
163+
162164
$scope.$on('$destroy', function() {
163165
if (scrollViewOptions) {
164166
scrollViewOptions.scrollingComplete = noop;

Diff for: js/angular/directive/sideMenuContent.js

+16
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,22 @@ function($timeout, $ionicGesture, $window) {
133133
element: element[0],
134134
onDrag: function() {},
135135
endDrag: function() {},
136+
setCanScroll: function(canScroll) {
137+
var c = $element[0].querySelector('.scroll');
138+
139+
if(!c) {
140+
return;
141+
}
142+
143+
var content = angular.element(c.parentElement);
144+
if(!content) {
145+
return;
146+
}
147+
148+
// freeze our scroll container if we have one
149+
var scrollScope = content.scope();
150+
scrollScope.scrollCtrl && scrollScope.scrollCtrl.freezeScrollShut(!canScroll);
151+
},
136152
getTranslateX: function() {
137153
return $scope.sideMenuContentTranslateX || 0;
138154
},

Diff for: js/utils/poly.js

+25
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
ionic.CSS.TRANSITION = [];
77
ionic.CSS.TRANSFORM = [];
88

9+
ionic.EVENTS = {};
10+
911
(function() {
1012

1113
// transform
@@ -41,6 +43,29 @@
4143
ionic.CSS.TRANSITIONEND = (isWebkit ? 'webkitTransitionEnd ' : '') + 'transitionend';
4244
})();
4345

46+
(function() {
47+
var touchStartEvent = 'touchstart'
48+
var touchMoveEvent = 'touchmove'
49+
var touchEndEvent = 'touchend'
50+
var touchCancelEvent = 'touchcancel'
51+
if (window.navigator.pointerEnabled) {
52+
touchStartEvent = 'pointerdown';
53+
touchMoveEvent = 'pointermove';
54+
touchEndEvent = 'pointerup';
55+
touchCancelEvent = 'pointercancel';
56+
} else if (window.navigator.msPointerEnabled) {
57+
touchStartEvent = 'MSPointerDown';
58+
touchMoveEvent = 'MSPointerMove';
59+
touchEndEvent = 'MSPointerUp';
60+
touchCancelEvent = 'MSPointerCancel';
61+
}
62+
63+
ionic.EVENTS.touchstart = touchStartEvent;
64+
ionic.EVENTS.touchmove = touchMoveEvent;
65+
ionic.EVENTS.touchend = touchEndEvent;
66+
ionic.EVENTS.touchcancel = touchCancelEvent;
67+
})();
68+
4469
// classList polyfill for them older Androids
4570
// https://gist.github.com/devongovett/1381839
4671
if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') {

Diff for: js/views/scrollView.js

+3
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,9 @@ ionic.views.Scroll = ionic.views.View.inherit({
411411
return self.options.freeze;
412412
};
413413

414+
// We can just use the standard freeze pop in our mouth
415+
self.freezeShut = self.freeze;
416+
414417
self.setScrollStart = function() {
415418
ionic.scroll.isScrolling = Math.abs(ionic.scroll.lastTop - self.__scrollTop) > 1;
416419
clearTimeout(self.scrollTimer);

Diff for: js/views/scrollViewNative.js

+23-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
var self = this;
1010
self.__container = self.el = options.el;
1111
self.__content = options.el.firstElementChild;
12+
// Whether scrolling is frozen or not
13+
self.__frozen = false;
1214
self.isNative = true;
1315

1416
self.__scrollTop = self.el.scrollTop;
@@ -60,7 +62,13 @@
6062
}, 80);
6163
};
6264

63-
self.freeze = NOOP;
65+
self.freeze = function(shouldFreeze) {
66+
self.__frozen = shouldFreeze;
67+
};
68+
// A more powerful freeze pop that dominates all other freeze pops
69+
self.freezeShut = function(shouldFreezeShut) {
70+
self.__frozenShut = shouldFreezeShut;
71+
};
6472

6573
self.__initEventHandlers();
6674
},
@@ -442,12 +450,23 @@
442450
self.resize();
443451
};
444452

453+
self.handleTouchMove = function(e) {
454+
if(self.__frozen || self.__frozenShut) {
455+
e.preventDefault();
456+
e.stopPropagation();
457+
return false;
458+
}
459+
}
460+
445461
container.addEventListener('scroll', self.onScroll);
446462

447463
//Broadcasted when keyboard is shown on some platforms.
448464
//See js/utils/keyboard.js
449465
container.addEventListener('scrollChildIntoView', self.scrollChildIntoView);
450466

467+
container.addEventListener(ionic.EVENTS.touchstart, self.handleTouchMove);
468+
container.addEventListener(ionic.EVENTS.touchmove, self.handleTouchMove);
469+
451470
// Listen on document because container may not have had the last
452471
// keyboardActiveElement, for example after closing a modal with a focused
453472
// input and returning to a previously resized scroll view in an ion-content.
@@ -466,6 +485,9 @@
466485
container.removeEventListener('scrollChildIntoView', self.scrollChildIntoView);
467486
container.removeEventListener('resetScrollView', self.resetScrollView);
468487

488+
container.removeEventListener(ionic.EVENTS.touchstart, self.handleTouchMove);
489+
container.removeEventListener(ionic.EVENTS.touchmove, self.handleTouchMove);
490+
469491
ionic.tap.removeClonedInputs(container, self);
470492

471493
delete self.__container;

Diff for: scss/_menu.scss

+6-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@
3535
.menu-open .menu-content .pane,
3636
.menu-open .menu-content .scroll-content {
3737
pointer-events: none;
38-
//overflow: hidden;
38+
}
39+
.menu-open .menu-content .scroll-content .scroll {
40+
pointer-events: none;
41+
}
42+
.menu-open .menu-content .scroll-content:not(.overflow-scroll) {
43+
overflow: hidden;
3944
}
4045

4146
.grade-b .menu-content,

Diff for: test/html/sideMenu.html

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ <h1>Content</h1>
2828
Sup
2929
<ion-option-button class="button-positive">Hello</ion-option-button>
3030
</ion-item>
31+
<a href="#" class="item" ng-repeat="item in list">
32+
{{item.text}}
33+
</a>
3134
</ion-list>
3235
</ion-content>
3336
</ion-side-menu-content>

0 commit comments

Comments
 (0)