Html 聚焦输入时 iOS 上的触摸滚动问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25596960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 02:37:05  来源:igfitidea点击:

Issues with touch scroll on iOS when focusing inputs

htmliosinputscroll

提问by Mindastic

I am having some issues with a scrollable div on iOS. When trying to scroll by touching outside an input, it scrolls ok without any problem but when I try to scroll and I touch an input to start scrolling (there are a lot of chances that it happens because it is a div with a lot of inputs) it scrolls the whole window instead scrolling the div. I don't have that problem either in desktop or Android. I found a similar question (iOS HTML Input Tag Stops Scrolling in Scrollable Element) but it doesn't have any answer either. While I don't find any good solution, I decided to prevent the event touchmovewhen the user touches an input, but it is not exactly what I want.

我在 iOS 上的可滚动 div 遇到了一些问题。当尝试通过触摸输入外部进行滚动时,它可以正常滚动而没有任何问题,但是当我尝试滚动并触摸输入以开始滚动时(发生这种情况的可能性很大,因为它是一个有很多输入的 div ) 它滚动整个窗口而不是滚动 div。我在桌面或 Android 中都没有这个问题。我发现了一个类似的问题(iOS HTML Input Tag Stops Scrolling in Scrollable Element)但它也没有任何答案。虽然我没有找到任何好的解决方案,但我决定touchmove在用户触摸输入时阻止该事件,但这并不是我想要的。

Maybe someone already faced this problem and can help. I would really appreciate it, thanks in advance.

也许有人已经遇到了这个问题并且可以提供帮助。我真的很感激,提前致谢。

回答by mjimcua

To get native momentum scrolling on iOS 5+, you'll need:

要在 iOS 5+ 上获得原生动量滚动,您需要:

div {
  overflow: scroll;
  -webkit-overflow-scrolling: touch;
}

Source: Overflow

来源:溢出

Maybe you also need:

也许你还需要:

div > * {
    -webkit-transform: translateZ(0px);
}

Source: Similar question in Stack Overflow

来源:Stack Overflow 中的类似问题

Source 2: Another similar question

来源 2:另一个类似的问题

回答by Dotgreg

This stuff made me crazy too, after testing everything, I found the following answer from Thomas Bachem hereworking and made it simpler in jquery.

这些东西也让我发疯了,在测试了一切之后,我找到了 Thomas Bachem 的以下答案在这里工作,并在 jquery 中使它更简单。

Just add a class scrollFixto the inputs and you are ready to go. (or directly apply that js to any inputs/textarea using$('input, textarea')

只需scrollFix在输入中添加一个类,您就可以开始使用了。(或直接将该 js 应用到任何输入/文本区域使用$('input, textarea')

Now when you touch and scroll on an input on iOS 8+, the input get all its "pointer-events" disabled (including the problematic behavior). Those "pointer-events" are enabled when we detect a simple touch.

现在,当您在 iOS 8+ 上触摸并滚动输入时,输入会禁用所有“指针事件”(包括有问题的行为)。当我们检测到简单的触摸时,就会启用这些“指针事件”。

$('.scrollFix').css("pointer-events","none");

$('body').on('touchstart', function(e) {
    $('.scrollFix').css("pointer-events","auto");
});
$('body').on('touchmove', function(e) {
    $('.scrollFix').css("pointer-events","none");
});
$('body').on('touchend', function(e) {
    setTimeout(function() {
        $('.scrollFix').css("pointer-events", "none");
    },0);
});

回答by ecairol

html { 
    overflow: scroll; 
    -webkit-overflow-scrolling: touch;
}

回答by Alex K

Hacky workaround, but by doing this I was able to make scrolling work even on form inputs. The JS forces a reflow in the rendering engine, which is where the bug in iOS8 Safari lies. Changing the height to auto also improved scrolling when focusedon a form element, since scrolling is forcibly handled by the browser when focused.

hacky 解决方法,但通过这样做,我甚至可以在表单输入上进行滚动工作。JS 强制渲染引擎中的重排,这是 iOS8 Safari 中的错误所在。将高度更改为自动还可以改善聚焦在表单元素上时的滚动,因为聚焦时浏览器会强制处理滚动。

Markup:

标记:

<div class="modal-backdrop-container">
  <div class="modal-backdrop">
    <div class="modal> <!-- Content --> </div>
  </div>
</div>

CSS:

CSS:

.modal-backdrop-container {
    z-index: 10;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    height: 100%;
}
.modal-backdrop {
    z-index: 10;
    height: 100%;
    background-color: rgba(255,255,255,0.5);
    overflow: auto;
    overflow-x: hidden;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
}
.modal {
    position: relative;
    width: 400px;
    max-width: 100%;
    margin: auto;
    background-color: white;
}

JS:

JS:

// reflow when changing input focus
        $modalInputs = $('.modal').find(':input');
        modalInputs.on('focus', function() {
            var offsetHeight = modal.$backdrop[0].offsetHeight;
            modal.$backdropContainer.css({
                'height': 'auto'
            });
        });
        modalInputs.on('blur', function() {
            var offsetHeight = modal.$backdrop[0].offsetHeight;
            modal.$backdropContainer.css({
                'height': ''
            });
        });

Not sure of the var offsetHeight = modal.$backdrop[0].offsetHeight;line is needed, since both this and changing the height value should force a reflow.

不确定var offsetHeight = modal.$backdrop[0].offsetHeight;是否需要这条线,因为这和改变高度值都应该强制回流。