Skip to content

Commit

Permalink
feat(menu): better scroll restrict. Fixes #4869
Browse files Browse the repository at this point in the history
  • Loading branch information
mlynch committed Dec 29, 2015
1 parent 1ec38ac commit fe3aeac
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 7 deletions.
1 change: 1 addition & 0 deletions js/angular/controller/scrollController.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ function($scope,
};

self.freezeScroll = scrollView.freeze;
self.freezeScrollShut = scrollView.freezeShut;

self.freezeAllScrolls = function(shouldFreeze) {
for (var i = 0; i < $ionicScrollDelegate._instances.length; i++) {
Expand Down
10 changes: 5 additions & 5 deletions js/angular/controller/sideMenuController.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,10 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
// equal 0, otherwise remove the class from the body element
$ionicBody.enableClass((percentage !== 0), 'menu-open');

freezeAllScrolls(false);
self.content.setCanScroll(percentage == 0);
};

/*
function freezeAllScrolls(shouldFreeze) {
if (shouldFreeze && !self.isScrollFreeze) {
$ionicScrollDelegate.freezeAllScrolls(shouldFreeze);
Expand All @@ -169,6 +170,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
}
self.isScrollFreeze = shouldFreeze;
}
*/

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

// End a drag with the given event
self._endDrag = function(e) {
freezeAllScrolls(false);

if (isAsideExposed) return;

if (isDragging) {
Expand Down Expand Up @@ -359,7 +359,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io

if (isDragging) {
self.openAmount(offsetX + (lastX - startX));
freezeAllScrolls(true);
self.content.setCanScroll(false);
}
};

Expand Down Expand Up @@ -443,7 +443,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
}

// ensure scrolls are unfrozen
freezeAllScrolls(false);
self.content.setCanScroll(true);
});

self.initialize({
Expand Down
2 changes: 2 additions & 0 deletions js/angular/directive/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ function($timeout, $controller, $ionicBind, $ionicConfig) {
scrollViewOptions: scrollViewOptions
});

$scope.scrollCtrl = scrollCtrl;

$scope.$on('$destroy', function() {
if (scrollViewOptions) {
scrollViewOptions.scrollingComplete = noop;
Expand Down
16 changes: 16 additions & 0 deletions js/angular/directive/sideMenuContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,22 @@ function($timeout, $ionicGesture, $window) {
element: element[0],
onDrag: function() {},
endDrag: function() {},
setCanScroll: function(canScroll) {
var c = $element[0].querySelector('.scroll');

if(!c) {
return;
}

var content = angular.element(c.parentElement);
if(!content) {
return;
}

// freeze our scroll container if we have one
var scrollScope = content.scope();
scrollScope.scrollCtrl && scrollScope.scrollCtrl.freezeScrollShut(!canScroll);
},
getTranslateX: function() {
return $scope.sideMenuContentTranslateX || 0;
},
Expand Down
25 changes: 25 additions & 0 deletions js/utils/poly.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
ionic.CSS.TRANSITION = [];
ionic.CSS.TRANSFORM = [];

ionic.EVENTS = {};

(function() {

// transform
Expand Down Expand Up @@ -41,6 +43,29 @@
ionic.CSS.TRANSITIONEND = (isWebkit ? 'webkitTransitionEnd ' : '') + 'transitionend';
})();

(function() {
var touchStartEvent = 'touchstart'
var touchMoveEvent = 'touchmove'
var touchEndEvent = 'touchend'
var touchCancelEvent = 'touchcancel'
if (window.navigator.pointerEnabled) {
touchStartEvent = 'pointerdown';
touchMoveEvent = 'pointermove';
touchEndEvent = 'pointerup';
touchCancelEvent = 'pointercancel';
} else if (window.navigator.msPointerEnabled) {
touchStartEvent = 'MSPointerDown';
touchMoveEvent = 'MSPointerMove';
touchEndEvent = 'MSPointerUp';
touchCancelEvent = 'MSPointerCancel';
}

ionic.EVENTS.touchstart = touchStartEvent;
ionic.EVENTS.touchmove = touchMoveEvent;
ionic.EVENTS.touchend = touchEndEvent;
ionic.EVENTS.touchcancel = touchCancelEvent;
})();

// classList polyfill for them older Androids
// https://gist.github.com/devongovett/1381839
if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') {
Expand Down
3 changes: 3 additions & 0 deletions js/views/scrollView.js
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,9 @@ ionic.views.Scroll = ionic.views.View.inherit({
return self.options.freeze;
};

// We can just use the standard freeze pop in our mouth
self.freezeShut = self.freeze;

self.setScrollStart = function() {
ionic.scroll.isScrolling = Math.abs(ionic.scroll.lastTop - self.__scrollTop) > 1;
clearTimeout(self.scrollTimer);
Expand Down
24 changes: 23 additions & 1 deletion js/views/scrollViewNative.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
var self = this;
self.__container = self.el = options.el;
self.__content = options.el.firstElementChild;
// Whether scrolling is frozen or not
self.__frozen = false;
self.isNative = true;

self.__scrollTop = self.el.scrollTop;
Expand Down Expand Up @@ -60,7 +62,13 @@
}, 80);
};

self.freeze = NOOP;
self.freeze = function(shouldFreeze) {
self.__frozen = shouldFreeze;
};
// A more powerful freeze pop that dominates all other freeze pops
self.freezeShut = function(shouldFreezeShut) {
self.__frozenShut = shouldFreezeShut;
};

self.__initEventHandlers();
},
Expand Down Expand Up @@ -442,12 +450,23 @@
self.resize();
};

self.handleTouchMove = function(e) {
if(self.__frozen || self.__frozenShut) {
e.preventDefault();
e.stopPropagation();
return false;
}
}

container.addEventListener('scroll', self.onScroll);

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

container.addEventListener(ionic.EVENTS.touchstart, self.handleTouchMove);
container.addEventListener(ionic.EVENTS.touchmove, self.handleTouchMove);

// Listen on document because container may not have had the last
// keyboardActiveElement, for example after closing a modal with a focused
// input and returning to a previously resized scroll view in an ion-content.
Expand All @@ -466,6 +485,9 @@
container.removeEventListener('scrollChildIntoView', self.scrollChildIntoView);
container.removeEventListener('resetScrollView', self.resetScrollView);

container.removeEventListener(ionic.EVENTS.touchstart, self.handleTouchMove);
container.removeEventListener(ionic.EVENTS.touchmove, self.handleTouchMove);

ionic.tap.removeClonedInputs(container, self);

delete self.__container;
Expand Down
7 changes: 6 additions & 1 deletion scss/_menu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@
.menu-open .menu-content .pane,
.menu-open .menu-content .scroll-content {
pointer-events: none;
//overflow: hidden;
}
.menu-open .menu-content .scroll-content .scroll {
pointer-events: none;
}
.menu-open .menu-content .scroll-content:not(.overflow-scroll) {
overflow: hidden;
}

.grade-b .menu-content,
Expand Down
3 changes: 3 additions & 0 deletions test/html/sideMenu.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ <h1>Content</h1>
Sup
<ion-option-button class="button-positive">Hello</ion-option-button>
</ion-item>
<a href="#" class="item" ng-repeat="item in list">
{{item.text}}
</a>
</ion-list>
</ion-content>
</ion-side-menu-content>
Expand Down

0 comments on commit fe3aeac

Please sign in to comment.