iOS Safari/Chrome - Unwanted scrolling when focusing an input inside the modal iOS Safari/Chrome - Unwanted scrolling when focusing an input inside the modal ios ios

iOS Safari/Chrome - Unwanted scrolling when focusing an input inside the modal


Just adding an answer here in case people stumble upon this question (rather than your other question, which has a great demo to illustrate this issue)

We are facing a similar issue at work. As you mentioned, the offset is always ~50% of the height of the page, which happens regardless of where your initial offset is.

In the past, when I observed a similar "jumping" with earlier iOS versions (albeit, much less dramatic jumping), I have usually worked around this by applying position: fixed (or relative) to the body (which allows overflow: hidden to properly work).

However, this has the unattended consequence of jumping the user back to the top of the page, if they've scrolled down.

So, if you're open to addressing this issue with some JavaScript, here's a fix/hack I've thrown together:

// Tapping into swal eventsonOpen: function () {  var offset = document.body.scrollTop;  document.body.style.top = (offset * -1) + 'px';  document.body.classList.add('modal--opened');},onClose: function () {  var offset = parseInt(document.body.style.top, 10);  document.body.classList.remove('modal--opened');  document.body.scrollTop = (offset * -1);}

And what the CSS looks like:

.modal--opened {  position: fixed;  left: 0;  right: 0;}

Here's a fork of your demo page (from your other question), to illustrate: https://jpattishall.github.io/sweetalert2/ios-bug.html

And for those who are looking for a more general fix, you could do something like the following when opening/closing a modal:

function toggleModal() {    var offset;    if (document.body.classList.contains('modal--opened')) {        offset = parseInt(document.body.style.top, 10);        document.body.classList.remove('modal--opened');        document.body.scrollTop = (offset * -1);    } else {        offset = document.body.scrollTop;        document.body.style.top = (offset * -1) + 'px';        document.body.classList.add('modal--opened');    }}

Edit: To avoid the "shifting/unshifting" on desktops, I would suggest feature detection/ua sniffing to apply this to only mobile safari.


I have experienced this issue as well. A short explanation is that iOS Safari will try to auto scroll to any input that is focused on and in this particular case the focused element is within a fixed positioned element. Safari seems to struggle with finding the fixed position element when it wants to center the element on the screen hence the background scrolling.

One possible fix is to add a touchstart event listener to the input field and calculate the current position of the overlay, change the positioning to absolute and update the top/left position to place the overlay back where it was on the screen when fixed positioned, and finally add a new blur listener to reset the overlay back to fixed positioning when leaving focus/blurring on the input. This should prevent the page from scrolling. I suggest using touchstart because it should trigger before the focus event at which case the page will already start scrolling. Safari should be able to find and center the absolute positioned overlay when the focus event is triggered.


So i have solved this and tested on my Iphone 5, don't have Ipad to check.I have disable overflow:hidden in my solution, you can add, If you want to disable scroll all in one for all modals.Solution is to add basically height and position property to both html and body element.

html, body {   position:relative;   /*overflow:hidden;*/   height: 100%;}

So, that only when you focus on input, height and position will be defined, i have already coded this solution from your repo, i will send you a pull request. I have also added browserSync in your gulp setup. Therefore, Now it will be easy to test across any device.

Cheers!

EDIT: another way, if above solution don't work for some reason. then,

 /*  * @summary touch handler; will remove touch ability  * @author yeomann  */  function Touchyhandler(e) {    e.preventDefault();  }

and later pragmatically add and remove touch listener like this

//to adddocument.addEventListener('touchmove', Touchyhandler, false); //to remove   document.removeEventListener('touchmove', Touchyhandler);

above js solution tested on IOS 9.3.2 work like charm for me]