web-dev-qa-db-ja.com

iPhone Webアプリケーションでスクロールを無効にしますか?

IPhone WebアプリでWebページのスクロールを完全に無効にする方法はありますか?私はグーグルに投稿された多くのものを試しましたが、どれもうまくいかないようです。

現在のヘッダー設定は次のとおりです。

_<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;"/>
<meta name="Apple-mobile-web-app-capable" content="yes"/>
_

document.body.addEventListener('touchmove', function(e){ e.preventDefault(); });

動作しないようです。

57
Stefan Kendall

'self.webView.scrollView.bounces = NO;'

アプリケーションのmainViewController.mファイルの「viewDidLoad」にこの1行を追加するだけです。 Xcodeで開いて追加できます。

これにより、ラバーバンドバウンスのないページが作成され、アプリビューのスクロールが有効になります。

10
Chait

touchstartの代わりにtouchmoveイベントに変更します。 One Finger Events では、パン中にイベントが送信されないため、touchmoveは遅すぎる可能性があります。

本文ではなくドキュメントにリスナーを追加しました。

例:

document.ontouchstart = function(e){ 
    e.preventDefault(); 
}
56
drawnonward
document.addEventListener('touchstart', function (e) {
    e.preventDefault();
});

既存のイベントハンドラを上書きする危険があるため、ontouchmoveプロパティを使用してイベントハンドラを登録しないでください。代わりに addEventListener を使用してください(MDNページのIEに関するメモを参照)。

touchstartまたはwindowdocumentイベントのデフォルトを防止すると、下降領域のスクロールが無効になることに注意してください。

ドキュメントのスクロールを防ぎ、他のすべてのイベントはそのままにしておくには、touchmoveに続く最初のtouchstartイベントのデフォルトを防ぎます。

var firstMove;

window.addEventListener('touchstart', function (e) {
    firstMove = true;
});

window.addEventListener('touchmove', function (e) {
    if (firstMove) {
        e.preventDefault();

        firstMove = false;
    }
});

これが機能する理由は、モバイルSafariが最初の動きを使用して、ドキュメントの本文がスクロールされているかどうかを判断しているためです。私はこれを実現しながら、より洗練されたソリューションを考案しました。

これが機能しなくなる場合、より洗練された解決策は、touchTarget要素とその親を検査し、スクロールできる方向のマップを作成することです。次に、最初のtouchmoveイベントを使用してスクロール方向を検出し、ドキュメントまたはターゲット要素(またはターゲット要素の親のいずれか)をスクロールするかどうかを確認します。

var touchTarget,
    touchScreenX,
    touchScreenY,
    conditionParentUntilTrue,
    disableScroll,
    scrollMap;

conditionParentUntilTrue = function (element, condition) {
    var outcome;

    if (element === document.body) {
        return false;
    }

    outcome = condition(element);

    if (outcome) {
        return true;
    } else {
        return conditionParentUntilTrue(element.parentNode, condition);
    }
};

window.addEventListener('touchstart', function (e) {
    touchTarget = e.targetTouches[0].target;
    // a boolean map indicating if the element (or either of element parents, excluding the document.body) can be scrolled to the X direction.
    scrollMap = {}

    scrollMap.left = conditionParentUntilTrue(touchTarget, function (element) {
        return element.scrollLeft > 0;
    });

    scrollMap.top = conditionParentUntilTrue(touchTarget, function (element) {
        return element.scrollTop > 0;
    });

    scrollMap.right = conditionParentUntilTrue(touchTarget, function (element) {
        return element.scrollWidth > element.clientWidth &&
               element.scrollWidth - element.clientWidth > element.scrollLeft;
    });

    scrollMap.bottom =conditionParentUntilTrue(touchTarget, function (element) {
        return element.scrollHeight > element.clientHeight &&
               element.scrollHeight - element.clientHeight > element.scrollTop;
    });

    touchScreenX = e.targetTouches[0].screenX;
    touchScreenY = e.targetTouches[0].screenY;
    disableScroll = false;
});

window.addEventListener('touchmove', function (e) {
    var moveScreenX,
        moveScreenY;

    if (disableScroll) {
        e.preventDefault();

        return;
    }

    moveScreenX = e.targetTouches[0].screenX;
    moveScreenY = e.targetTouches[0].screenY;

    if (
        moveScreenX > touchScreenX && scrollMap.left ||
        moveScreenY < touchScreenY && scrollMap.bottom ||
        moveScreenX < touchScreenX && scrollMap.right ||
        moveScreenY > touchScreenY && scrollMap.top
    ) {
        // You are scrolling either the element or its parent.
        // This will not affect document.body scroll.
    } else {
        // This will affect document.body scroll.

        e.preventDefault();

        disableScroll = true;
    }
});

これが機能する理由は、モバイルSafariが最初のタッチ移動を使用して、ドキュメント本文がスクロールされているのか、要素(またはターゲット要素の親)がこの決定に従うのかを判断するためです。

16
Gajus

Jquery 1.7+を使用している場合、これはうまく機能します。

$("donotscrollme").on("touchmove", false);
13
Rob Lauer

これは動作するはずです。上部または下部に灰色の領域はもうありません:)

<script type="text/javascript">
   function blockMove() {
      event.preventDefault() ;
}
</script>

<body ontouchmove="blockMove()">

ただし、これによりスクロール可能な領域も無効になります。スクロール可能な領域を維持し、上下のラバーバンド効果を削除する場合は、こちらを参照してください: https://github.com/joelambert/ScrollFix

12
kaleazy

無効にする:

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

有効にする:

document.ontouchstart = function(e){ return true; }
10

メタタグを機能させるには、ホーム画面からページを起動する必要があります。

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

実際に私が見つけた最良の選択であり、入力フィールドをタップしたり、ドラッグ可能なjQuery UIを使用して物事をドラッグしたりすることができますが、ページのスクロールは停止します。

1
Josh Bedo

私は上記の答え、特にガジュの答えを試しましたが、どれもうまくいきません。最後に、本体のみがスクロールせず、Webアプリ内の他のスクロールセクションがすべて正常に機能するという問題を解決するために、以下の回答を見つけました。体の位置を固定するだけです:

body {

height: 100%;
overflow: hidden;
width: 100%;
position: fixed;
}
0
TheeBen