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

感情迁移 提交于 2019-12-23 08:23:08

问题


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 become 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 commit: limonte/sweetalert2/commit/4a2d36b


回答1:


We 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.




回答2:


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);



回答3:


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



来源:https://stackoverflow.com/questions/39626302/ios-chrome-safari-unwanted-scrolling-when-focusing-an-input-inside-the-modal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!