web-dev-qa-db-ja.com

document.ontouchmoveとiOS 5でのスクロール

iOS 5は、JavaScript/Webアプリに多くの素晴らしいものをもたらしました。それらの1つはスクロールの改善です。追加する場合

-webkit-overflow-scroll:touch;

textarea要素のスタイルに合わせて、スクロールは1本の指でうまく機能します。

しかし、問題があります。画面全体がスクロールしないようにするには、Webアプリに次のコード行を追加することをお勧めします。

document.ontouchmove = function(e) {e.preventDefault()};

ただし、これは新しいスクロールを無効にします。

誰もがテキストエリア内で新しいスクロールを許可する素敵な方法を持っていますが、フォーム全体をスクロールすることはできませんか?

47
ghenne

UpdateAlvaroのコメント ごとに、このソリューションはiOS 11.3以降では動作しなくなる可能性があります。

PreventDefaultが呼び出されるかどうかを選択することにより、スクロールを許可できるはずです。例えば。、

document.ontouchmove = function(e) {
    var target = e.currentTarget;
    while(target) {
        if(checkIfElementShouldScroll(target))
            return;
        target = target.parentNode;
    }

    e.preventDefault();
};

または、イベントがドキュメントレベルに到達しないようにすることで機能する場合があります。

elementYouWantToScroll.ontouchmove = function(e) {
    e.stopPropagation();
};

Edit後で読んでいる人にとっては、別の答えが機能し、はるかに簡単です。

56
Brian Nickel

ブライアンニッケルの答えの唯一の問題は、(user1012566が言及したように)スクロール可能領域の境界に達したときにstopPropagationがバブリングを妨げないことです。次の方法でこれを防ぐことができます。

elem.addEventListener('touchstart', function(event){
    this.allowUp = (this.scrollTop > 0);
    this.allowDown = (this.scrollTop < this.scrollHeight - this.clientHeight);
    this.prevTop = null; 
    this.prevBot = null;
    this.lastY = event.pageY;
});

elem.addEventListener('touchmove', function(event){
    var up = (event.pageY > this.lastY), 
        down = !up;

    this.lastY = event.pageY;

    if ((up && this.allowUp) || (down && this.allowDown)) 
        event.stopPropagation();
    else 
        event.preventDefault();
});
22
1nfiniti

PhoneGapでこれを達成しようとしている人は、cordova.plistUIWebViewBounceの値をNOに設定します。私がこれに年齢を費やしている人の助けになることを願っています(私がそうであったように)。

16
Andrew Plummer

ScrollFixは完璧なソリューションのようです。私はそれをテストし、それは魅力のように機能します!

https://github.com/joelambert/ScrollFix

/**
 * ScrollFix v0.1
 * http://www.joelambert.co.uk
 *
 * Copyright 2011, Joe Lambert.
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 */

var ScrollFix = function(elem) {
    // Variables to track inputs
    var startY, startTopScroll;

    elem = elem || document.querySelector(elem);

    // If there is no element, then do nothing  
    if(!elem)
        return;

    // Handle the start of interactions
    elem.addEventListener('touchstart', function(event){
        startY = event.touches[0].pageY;
        startTopScroll = elem.scrollTop;

        if(startTopScroll <= 0)
            elem.scrollTop = 1;

        if(startTopScroll + elem.offsetHeight >= elem.scrollHeight)
            elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
    }, false);
};
6
vladaman

StopPropagationとネイティブdivスクロールに関する既知の問題を発見するのはイライラしていました。 onTouchMoveがバブリングするのを防ぐようには見えないため、divの境界を超えてスクロールすると(上部が上に、または下部が下に)、ページ全体がバウンドします。

詳細な議論 here および here

2
user1012566