From 74de015c221962aae8e48c1a81481ec6fc706f5e Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Sun, 14 Sep 2014 23:18:55 -0500 Subject: [PATCH] fix(keyboard): android scroll stuck MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a state change happens, ensure the keyboard is hidden. When a keyboard is hidden, ensure all pending timers our cleared. When resetting scrollView, ensure it’s only doing it when it has to. For testing: #1670 #2192 --- js/angular/service/viewService.js | 5 + js/utils/keyboard.js | 66 ++++-- js/views/scrollView.js | 12 +- test/html/input.html | 363 +++++++++++++++++++++--------- 4 files changed, 315 insertions(+), 131 deletions(-) diff --git a/js/angular/service/viewService.js b/js/angular/service/viewService.js index 3853f498e8..edc1d6b095 100644 --- a/js/angular/service/viewService.js +++ b/js/angular/service/viewService.js @@ -30,6 +30,11 @@ function($rootScope, $state, $location, $document, $animate, $ionicPlatform, $io $ionicViewService.disableRegisterByTagName('ion-side-menus'); } + // always reset the keyboard state when change stage + $rootScope.$on('$stateChangeStart', function(){ + ionic.keyboard.hide(); + }); + $rootScope.$on('viewState.changeHistory', function(e, data) { if(!data) return; diff --git a/js/utils/keyboard.js b/js/utils/keyboard.js index 9ab83e782f..dd5929b469 100644 --- a/js/utils/keyboard.js +++ b/js/utils/keyboard.js @@ -66,6 +66,7 @@ var keyboardIsOpen; var keyboardActiveElement; var keyboardFocusOutTimer; var keyboardFocusInTimer; +var keyboardPollHeightTimer; var keyboardLastShow = 0; var KEYBOARD_OPEN_CSS = 'keyboard-open'; @@ -75,6 +76,41 @@ ionic.keyboard = { isOpen: false, height: null, landscape: false, + + hide: function() { + clearTimeout(keyboardFocusInTimer); + clearTimeout(keyboardFocusOutTimer); + clearTimeout(keyboardPollHeightTimer); + + console.log('keyboardHide'); + ionic.keyboard.isOpen = false; + + ionic.trigger('resetScrollView', { + target: keyboardActiveElement + }, true); + + ionic.requestAnimationFrame(function(){ + document.body.classList.remove(KEYBOARD_OPEN_CSS); + }); + + // the keyboard is gone now, remove the touchmove that disables native scroll + if (window.navigator.msPointerEnabled) { + document.removeEventListener("MSPointerMove", keyboardPreventDefault); + } else { + document.removeEventListener('touchmove', keyboardPreventDefault); + } + document.removeEventListener('keydown', keyboardOnKeyDown); + + if( keyboardHasPlugin() ) { + cordova.plugins.Keyboard.close(); + } + }, + + show: function() { + if( keyboardHasPlugin() ) { + cordova.plugins.Keyboard.show(); + } + } }; function keyboardInit() { @@ -126,22 +162,23 @@ function keyboardSetShow(e) { keyboardFocusInTimer = setTimeout(function(){ if ( keyboardLastShow + 350 > Date.now() ) return; + console.log('keyboardSetShow'); keyboardLastShow = Date.now(); var keyboardHeight; var elementBounds = keyboardActiveElement.getBoundingClientRect(); var count = 0; - var pollKeyboardHeight = setInterval(function(){ + keyboardPollHeightTimer = setInterval(function(){ keyboardHeight = keyboardGetHeight(); if (count > 10){ - clearInterval(pollKeyboardHeight); + clearInterval(keyboardPollHeightTimer); //waited long enough, just guess keyboardHeight = 275; } if (keyboardHeight){ + clearInterval(keyboardPollHeightTimer); keyboardShow(e.target, elementBounds.top, elementBounds.bottom, keyboardViewportHeight, keyboardHeight); - clearInterval(pollKeyboardHeight); } count++; @@ -192,28 +229,7 @@ function keyboardShow(element, elementTop, elementBottom, viewportHeight, keyboa function keyboardFocusOut(e) { clearTimeout(keyboardFocusOutTimer); - keyboardFocusOutTimer = setTimeout(keyboardHide, 350); -} - -function keyboardHide() { - console.log('keyboardHide'); - ionic.keyboard.isOpen = false; - - ionic.trigger('resetScrollView', { - target: keyboardActiveElement - }, true); - - ionic.requestAnimationFrame(function(){ - document.body.classList.remove(KEYBOARD_OPEN_CSS); - }); - - // the keyboard is gone now, remove the touchmove that disables native scroll - if (window.navigator.msPointerEnabled) { - document.removeEventListener("MSPointerMove", keyboardPreventDefault); - } else { - document.removeEventListener('touchmove', keyboardPreventDefault); - } - document.removeEventListener('keydown', keyboardOnKeyDown); + keyboardFocusOutTimer = setTimeout(ionic.keyboard.hide, 350); } function keyboardUpdateViewportHeight() { diff --git a/js/views/scrollView.js b/js/views/scrollView.js index b74d971676..b0ab312462 100644 --- a/js/views/scrollView.js +++ b/js/views/scrollView.js @@ -687,11 +687,13 @@ ionic.views.Scroll = ionic.views.View.inherit({ self.resetScrollView = function(e) { //return scrollview to original height once keyboard has hidden - self.isScrolledIntoView = false; - container.style.height = ""; - container.style.overflow = ""; - self.resize(); - ionic.scroll.isScrolling = false; + if(self.isScrolledIntoView) { + self.isScrolledIntoView = false; + container.style.height = ""; + container.style.overflow = ""; + self.resize(); + ionic.scroll.isScrolling = false; + } }; //Broadcasted when keyboard is shown on some platforms. diff --git a/test/html/input.html b/test/html/input.html index c829c88c49..1e007301e9 100644 --- a/test/html/input.html +++ b/test/html/input.html @@ -44,6 +44,9 @@ .scroll { background: lightgreen; } + .keyboard-open .scroll-content{ + background: green; + } input, textarea { @@ -56,136 +59,279 @@
- - - - + - + + + -

- Click Tests - - Tap Inputs - - CSS Tests -

-
-