2

I ran across and issue with inputs inside modals.

When users open the modal it covers the whole page, is set to high z-index and position absolute. once users focus on input inside the modal, on ios whole page scrolls down for some reason.

I assume it is ios behaviour to scroll input field up a bit in order to allow some space for the keyboard, and as html for my modal is located at the bottom of the page, it tries to scroll to that.

I have tried overflow-y: hidden on body and attaching an event listener to it of event.preventDefault() once touchmove occures, while modal is open, these stop page from scrolling, even on ios users can't scroll, but once they focus on an input all of these seem to be ignored.

Ilja
  • 44,142
  • 92
  • 275
  • 498

3 Answers3

0

This answer worked for me. The other thing you need to do is make the text size in the input at least 16px, otherwise iOS forces it to do the annoying "zoom in" feature.

Pasted as well if you don't want to click the link.

//Set 2 global variables
var scrollTopPosition = 0;
var lastKnownScrollTopPosition = 0;

//when the document loads
$(document).ready(function(){

  //this only runs on the right platform -- this step is not necessary, it should work on all platforms
  if( navigator.userAgent.match(/iPhone|iPad|iPod/i) ) {

    //There is some css below that applies here
    $('body').addClass('platform-ios');

    //As you scroll, record the scrolltop position in global variable
    $(window).scroll(function () {
      scrollTopPosition = $(document).scrollTop();
    });

    //when the modal displays, set the top of the (now fixed position) body to force it to the stay in the same place
    $('.modal').on('show.bs.modal', function () {

      //scroll position is position, but top is negative
      $('body').css('top', (scrollTopPosition * -1));

      //save this number for later
      lastKnownScrollTopPosition = scrollTopPosition;
    });

    //on modal hide
    $('.modal').on('hidden.bs.modal', function () {

      //force scroll the body back down to the right spot (you cannot just use scrollTopPosition, because it gets set to zero when the position of the body is changed by bootstrap
      $('body').scrollTop(lastKnownScrollTopPosition);
    });
  }
});

css:

// You probably already have this, but just in case you don't
body.modal-open {
  overflow: hidden;
  width: 100%;
  height: 100%;
}
//only on this platform does it need to be fixed as well
body.platform-ios.modal-open {
  position: fixed;
}
Community
  • 1
  • 1
iamse7en
  • 609
  • 8
  • 21
0

with fontSize over 16 not working for me on vue2 and ios 16 :( and scrolling only on IOS :(

but...

<input v-model="value" @touchstart="touchStart" @touchend="touchEnd">

// and methods:

const touchStart = (e) => {
  e.target.readOnly = true
}

const touchEnd = (e) => {
  e.target.readOnly = false
  e.tartet.focus({preventScroll: true})
}

not perfect, but is working for me

0

Add this code to your script

https://gist.github.com/kiding/72721a0553fa93198ae2bb6eefaa3299

//reach out to that input field (When ever u r gonna click tofocus)
let inputField = document.getElementById("input_focused")

 /*
 * Method 1: Briefly change the opacity.
 * Element might "blink" on focus in some scenarios.
 */
inputField.addEventListener("focus", () => {
      methodOne.style.opacity = 0;
      setTimeout(() => methodOne.style.opacity = 1);
    });
 <section id="modal">
    <input id="input_focused">
  </section>
starball
  • 20,030
  • 7
  • 43
  • 238