Tested in Safari and Chrome - the same result, so I think it's iOS issue.
This happens only if there's an input inside the modal and I tap that input. In the same moment, that input gets focus and native iOS keyboard bee visible.
The page below modal in the same moment is automatically scrolled to 50% of its height. This behaviour is totally unwanted and I have no clue how to prevent this default iOS "feature".
Demo:
UPDATE: the fix mit: limonte/sweetalert2/mit/4a2d36b
Tested in Safari and Chrome - the same result, so I think it's iOS issue.
This happens only if there's an input inside the modal and I tap that input. In the same moment, that input gets focus and native iOS keyboard bee visible.
The page below modal in the same moment is automatically scrolled to 50% of its height. This behaviour is totally unwanted and I have no clue how to prevent this default iOS "feature".
Demo:
UPDATE: the fix mit: limonte/sweetalert2/mit/4a2d36b
Share Improve this question edited Apr 5, 2018 at 17:44 Limon Monte asked Sep 21, 2016 at 20:46 Limon MonteLimon Monte 54.4k49 gold badges187 silver badges219 bronze badges 6- Do you have setTimeout or setInterval functions in your javascript? – poashoas Commented Sep 21, 2016 at 20:51
-
Yes, input autofocus functionality works with
setTimeout()
because of animations – Limon Monte Commented Sep 21, 2016 at 21:39 - This happened only once in iOS Safari and it never happened after that. But in chrome it is happening every time. – Praveen Kumar Commented Sep 30, 2016 at 16:10
- What on Earth is going on with that gif? – Brian Leishman Commented Mar 1, 2018 at 13:53
- 1 thanks @Yvan, I updated the question. – Limon Monte Commented Apr 5, 2018 at 17:45
5 Answers
Reset to default 3We are facing a similar issue at work, and I stumbled upon this question with your (excellent) demo page.
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
(this 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 events
onOpen: 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, 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: One thing to note is that we didn't apply the fix to all devices/platforms blindly, just iOS Safari. I noticed in your other question that you weren't a fan of overflow: hidden due to the shifting of the page when the scrollbar appears/disappears (which I totally agree with). I would suggest just applying the JS to iOS devices only.
Resolved!!!!! Just please add those codes to your script
https://gist.github./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>
On iOS I had trouble with scroll events caused by setTimeout and setInterval (position the modal causes scrolling?). I found a solution somewhere with the following code.
Function.prototype.bind = function(parent) {
var f = this;
var args = [];
for (var a = 1; a < arguments.length; a++) {
args[args.length] = arguments[a];
}
var temp = function() {
return f.apply(parent, args);
}
return(temp);
}
setTimeout(function() {
// your animation stuff here
}.bind(this), 100);
One thing I can think of here is to probably add the Fast Click library to your code. Some iOS and Android timeout issues like the 300ms
delay are handled by Fast Click. It's worth a shot
Something else to check for is that the font size of the input field is above the minimum that will trigger a zoom on the input. I'm working from memory here, but I had a similar problem. Setting the input font size to 16px (again from memory) or more prevented iOS Safari from trying to zoom the input field and thus messing with the page scroll.