Skip to content
This repository has been archived by the owner on Dec 2, 2021. It is now read-only.

Scrollview is only partially shown (after blurring an input element, window scroll position isnt reset) #106

Closed
markmarijnissen opened this issue May 19, 2015 · 9 comments
Labels

Comments

@markmarijnissen
Copy link

2015-05-19 17 45 27

  1. Focus an input element (keyboard shows)
  2. Blur an input element (keyboard closes)
  3. Use RenderController to Show a famous-flex Scrollview
  4. Scrollview is partially shown, see screenshot.

Can you give any hint to how to fix this?

@IjzerenHein
Copy link
Owner

I'm assuming that's on Android?

@markmarijnissen
Copy link
Author

No, it's on iPhone5!

@IjzerenHein
Copy link
Owner

That is very strange because iOS doesn't change the viewport size when the keyboard is shown. It does however change the window.scrollTop in order to make sure the focused element isn't obscured by the keyboard. Does your input element appear on the bottom part of the screen?

@markmarijnissen
Copy link
Author

Yes!

The input element is halfway the screen, so iOS scrolls to the element to make sure it stays visible.

The solution was to call window.scroll(0,0) after the keyboard has closed.

Thanks Hein for the window.scrollTop hint!

@markmarijnissen markmarijnissen changed the title Scrollview strange resize bug Scrollview is only partially shown (after blurring an input element, window scroll position isnt reset) May 19, 2015
@markmarijnissen
Copy link
Author

I've rewritten some comments so that future readers can find the solution easily. Closing the issue now.

@IjzerenHein
Copy link
Owner

Awesome, glad that has been resolved :)

Btw, here is the code I use to deal with that exact same problem:

/**
 * Fixes that ensure everything runs without glitches on all
 * browsers and all platforms.
 *
 * @module
 */
define(function(require) {

  var ElementOutput = require('famous/core/ElementOutput');
  var Surface = require('famous/core/Surface');
  var browser = require('bowser').browser;
  var Engine = require('famous/core/Engine');

  /**
   * In case of Internet Explorer and Firefox, make sure the z-Index is
   * explicitely set so that all z-indexing is performed correctly.
   */
  if (browser.msie || browser.firefox) {
    var oldCommit = ElementOutput.prototype.commit;
    ElementOutput.prototype.commit = function(context) {
        oldCommit.call(this, context);
        if (this._element) {
            var zIndex = this._matrix[14];
            if (this._element.style.zIndex !== zIndex) {
                this._element.style.zIndex = zIndex;
            }
        }
    };
  }

  /**
   * There is a bug in recall which causes the latest setContent()
   * call to be ignored, if the element is removed from the DOM in
   * the next render-cycle. This causes some buttons to not update
   * properly always (sometimes they showed the loader or nothing).
   */
  Surface.prototype.recall = function recall(target) {
    if (!this._contentDirty) {
      var df = document.createDocumentFragment();
      while (target.hasChildNodes()) {
          df.appendChild(target.firstChild);
      }
      this.setContent(df);
    }
    else {
      this._contentDirty = true;
    }
  };

  /**
   * Sometimes, the browser scrolls the window up, hiding the top
   * part and exposing the empty bottom part. This seems to be related
   * to keyboard focus. This handler focus the scroll-position back to
   * 0, but only when there is no focused input or textarea. On mobile,
   * when an input or textarea is shown, it also shows the soft-keyboard
   * and the scrollTop is purposely changed by the browser. This situation
   * should be respected at all cost.
   */
  function _isActiveElementAnInput() {
    var activeElementType = (document.activeElement && document.activeElement.tagName) ? document.activeElement.tagName.toLowerCase() : '';
    return ((activeElementType === 'textarea') || (activeElementType === 'input'));
  }
  var iOSKeyboardHeights = {
    iPad: {
      landscape: 435,
      portrait: 348
    },
    iPhone: {
      landscape: 164,
      portrait: 254
    }
  };
  var maxScrollTopReached = false;
  var landscape = window.innerWidth > window.innerHeight;
  Engine.on('prerender', function() {

    // When an element has the focus, iOS scrolls the top of the body up to accomedate
    // for the input. We don't want this in our absolute positioned famo.us application, so
    // we scroll just ...
    var maxScrollTop = 0;
    var scrollTop = document.body.scrollTop;
    landscape = window.innerWidth > window.innerHeight;
    if (_isActiveElementAnInput()) {
      if (browser.ipad) {
        maxScrollTop = landscape ? iOSKeyboardHeights.iPad.landscape : iOSKeyboardHeights.iPad.portrait;
      }
      if (browser.iphone) {
        maxScrollTop = landscape ? iOSKeyboardHeights.iPhone.landscape : iOSKeyboardHeights.iPhone.portrait;
      }
    }
    if ((scrollTop > maxScrollTop) || (maxScrollTopReached && maxScrollTop)) {
      document.body.scrollTop = maxScrollTop;
      maxScrollTopReached = true;
    }
    else {
      maxScrollTopReached = false;
    }

    // When typing in an input or textarea, and the input or text-area touches the right
    // edge of the screen, the browser will scroll right a little bit to accomedate for
    // the text input. We don't want this in a famo.us application, and therefore force
    // scrollLeft to 0 when this situation is detected.
    if (document.body.scrollLeft !== 0) {
      if (_isActiveElementAnInput()) {
        //console.log('fixing scrollLeft:' + document.body.scrollLeft);
        document.body.scrollLeft = 0;
      }
    }
  });
});

@markmarijnissen
Copy link
Author

I'm using latest master and I don't like that you're manipulating my scroll positions! Can I disable this?

@IjzerenHein
Copy link
Owner

That code isn't in famous-flex if that is your question? It's just a snippet I use in my apps. Do whatever you want with it :)

@markmarijnissen
Copy link
Author

Oh yes, my mistake :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants