iOS Safari / Chrome - 将输入聚焦在模态内时不需要滚动

时间:2016-05-17 22:20:17

标签: javascript html ios css vertical-scrolling

在Safari和Chrome中测试过 - 结果相同,所以我认为这是iOS问题。

仅当模态中有输入并且我点击该输入时才会发生这种情况。在输入获得焦点并且原生iOS键盘变得可见的同一时刻。

同一时刻模态下方的页面会自动滚动到其高度的50%。这种行为是完全不需要的,我不知道如何防止这个默认的iOS"功能"。

演示:

enter image description here

8 个答案:

答案 0 :(得分:10)

如果人们偶然发现了这个问题(rather than your other question, which has a great demo to illustrate this issue

,请在此处添加答案

我们在工作中遇到类似的问题。正如您所提到的,偏移总是约为页面高度的50%,无论您的初始偏移位于何处,都会发生偏移。

在过去,当我观察到类似的"跳跃"对于早期的iOS版本(尽管跳跃性不那么戏剧化),我通常通过将position: fixed(或relative)应用于bodywhich allows overflow: hidden to properly work)来解决这个问题。

然而,如果用户已向下滚动,则会产生无人值守的后果:将用户跳回到页面顶部。

因此,如果您对某些JavaScript解决此问题持开放态度,我可以将修复/黑客放在一起:

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

CSS看起来像什么:

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

这是您的演示页面的分支(来自您的其他问题),以说明:https://jpattishall.github.io/sweetalert2/ios-bug.html

对于那些正在寻找更一般修复的人,你可以在打开/关闭模态时执行以下操作:

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

编辑:避免"转移/不转移"在台式机上,我建议使用功能检测/ ua嗅探将其应用于移动游侠。

答案 1 :(得分:1)

所以我已经解决了这个并在我的iPhone 5上进行了测试,没有Ipad可以检查。 我已在我的解决方案中禁用overflow:hidden,您可以添加,如果您要为所有模态禁用全部滚动。 解决方案是基本上为html和body元素添加height和position属性。

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

所以,只有当你专注于输入,高度和位置才会被定义,我已经从你的回购中编码了这个解决方案,我会发送一个拉取请求。 我还在你的gulp设置中添加了browserSync。因此,现在可以轻松地在任何设备上进行测试。

干杯!

编辑:另一种方式,如果上述解决方案由于某种原因不起作用。然后,

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

以后用语言添加和删除这样的触摸侦听器

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

在IOS 9.3.2上测试的js解决方案对我来说就像魅力一样工作]

答案 2 :(得分:1)

要阻止页面在x轴和y轴上滚动,我们在css中使用overflow: hidden;属性。

因此,如果我们将其应用于身体,

body {
    overflow: hidden !important;
}

它应该正常工作吗?

事实上,这实际上并不起作用,因为您在整个页面上都禁用了x和y滚动整个页面。

为了绕过这个,当模态处于活动状态时,我们可以使用一个javascript来向正文添加一个类。

首先我们必须为我们的身体添加一个id,<body id="body">这允许javascript识别身体。

其次,我们必须为我们的模态<div id="modal">添加一个id,同时允许javascript识别模态。

<script type="text/javascript">
    function modalActive() {
        if (document.getElementById("modal").classList.contains("active")) {
            document.getElementById("body").classList.add("modal-active");
        } else {
            getElementById("modal").classList.remove("active"));
            getElementById("body").classList.remove("modal-active"));           
        }
    }
</script>

对于启动的按钮和关闭模态,我们必须添加一个onclick事件,

<button onclick="modalActive()">Click Me!</button>

最重要的是我们必须将它添加到css文件中。

body {
    overflow: initial !important;
}

body.modal-active {
    overflow: hidden !important;
}

我们走了。

答案 3 :(得分:0)

我不是百分百肯定,但我可以想象以下内容:

当键盘出现时,窗口高度会降低,但scrollTop值仍然相同,因此网站会跳转到该值。当模态打开时,您可以将overflow:hidden添加到body。这将阻止模式“后面”滚动并可能解决您的问题。

答案 4 :(得分:0)

我也遇到过这个问题。一个简短的解释是iOS Safari将尝试自动滚动到任何聚焦的输入,在这种特殊情况下,聚焦元素位于固定的定位元素内。当Safari想要将元素置于屏幕中心因此背景滚动时,Safari似乎很难找到固定位置元素。

一种可能的解决方法是向输入字段添加touchstart事件侦听器并计算叠加层的当前位置,将定位更改为绝对位置并更新顶部/左侧位置以将叠加层放回原位置在固定定位的屏幕上,最后添加一个新的blur侦听器,以便在输入上留下焦点/模糊时将叠加重置回固定定位。这应该可以防止页面滚动。我建议使用touchstart因为它应该在focus事件之前触发,在这种情况下页面已经开始滚动。当focus事件被触发时,Safari应该能够找到并居中绝对定位的叠加层。

答案 5 :(得分:0)

我尝试了多种在html页面上为弹跳模态输入工作的东西。对我来说最简单的解决方案是在页面上打开模态

时向 body标签添加以下样式。

position: fixed;
width: 100%;

答案 6 :(得分:0)

添加此元数据( maximum-scale = 1,minimum-scale = 1 )以重置滚动,该滚动是在聚焦输入字段时发生的。

答案 7 :(得分:0)

升级到iPadOS 13后,我遇到了这个问题。我必须删除以下旧的JavaScript代码,这是解决旧版本中其他滚动问题所必需的:

function fixIpadKeyboardScrolling() {
   if ((Device.is("ipad") || Device.is("iphone"))) {
    console.log("Fixing iPad/iPhone floating bar bug");
    var inputs = document.getElementsByTagName("input");
    if (inputs.length) {
      for (var i = inputs.length - 1; i >= 0; i--) {
        addListener(inputs[i], "blur", function () {
          setTimeout(function () {
              window.scrollTo(document.body.scrollLeft, document.body.scrollTop);
          }, 0);
        });
      }
    }
    console.log(inputs.length + " input controls where edited to fix keyboard scrolling");
  }
}

如果升级后突然遇到此问题,则可能对您的应用程序应用了类似的代码。

在我的情况下,我添加了对safari mobile 13版本的检测,并且仅针对低于该版本的版本运行脚本。