web-dev-qa-db-ja.com

入力をフォーカスするときのiOSのタッチスクロールの問題

IOSのスクロール可能なdivで問題が発生しています。入力の外側をタッチしてスクロールしようとすると問題なくスクロールしますが、スクロールしようとして入力をタッチするとスクロールが開始されます)divをスクロールする代わりにウィンドウ全体をスクロールします。デスクトップでもAndroidでも問題はありません。同様の質問を見つけました( iOS HTML Input Tag Stops Scrolling in Scrollable Element )が、答えもありません。良い解決策は見つかりませんが、ユーザーが入力に触れたときにtouchmoveイベントを防ぐことにしましたが、それはまさに私が望むものではありません。

誰かがすでにこの問題に直面していて、助けてくれるかもしれません。事前に感謝します。

37
Mindastic

IOS 5以降でネイティブのモーメンタムスクロールを取得するには、次のものが必要です。

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

ソース: オーバーフロー

たぶんあなたも必要です:

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

ソース: スタックオーバーフローの同様の質問

ソース2: 別の同様の質問

39
mjimcua

このことも私を夢中にさせました。すべてをテストした後、Thomas Bachem here からの次の答えを見つけて、jqueryでよりシンプルにしました。

クラスscrollFixを入力に追加するだけで準備完了です。 (または、そのjsをinput/textarea using$('input, textarea')に直接適用します

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);
});
6
Dotgreg
html { 
    overflow: scroll; 
    -webkit-overflow-scrolling: touch;
}
1
ecairol

ハッキーな回避策ですが、これを行うことで、フォーム入力でもスクロールを動作させることができました。 JSはレンダリングエンジンのリフローを強制します。これはiOS8 Safariのバグが存在する場所です。高さをautoに変更すると、フォーム要素でfocusedの場合のスクロールも改善されました。スクロールは、フォーカスされるとブラウザによって強制的に処理されるためです。

マークアップ:

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

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:

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

var offsetHeight = modal.$backdrop[0].offsetHeight;行が必要です。これと高さの値を変更すると、リフローが強制されるためです。

0
Alex K