web-dev-qa-db-ja.com

Androidのchromeプルダウンから更新機能を無効にする

会社用の小さなHTML5 Webアプリケーションを作成しました。

このアプリケーションはアイテムのリストを表示し、すべてが正常に機能します。

このアプリケーションは主にAndroid電話とChromeでブラウザーとして使用されます。また、サイトはホーム画面に保存されるため、Android全体をアプリとして管理します(私が推測するWebViewを使用して)。

クロム ベータ版(およびAndroid System WebViewも考えます) 「プルダウンして更新」機能を導入しました( 例についてはこのリンクを参照 )。

これは便利な機能ですが、リストをナビゲートしているときにユーザーが更新を簡単にトリガーでき、アプリ全体がリロードされるため、何らかのメタタグ(またはJavaScriptのもの)で無効にできるかどうか疑問に思いました。

また、これはアプリケーションが必要としない機能です。

この機能はChromeベータ版でのみ利用可能であることは知っていますが、安定版アプリにも登場しているという感覚があります。

ありがとうございました!

編集:Chrome Betaをアンインストールし、ホーム画面に固定されたリンクが安定したChromeで開きます。そのため、固定リンクはChromeで始まり、Webビューではありません。

編集:今日(2015-03-19)リフレッシュプルダウンが安定したクロムになりました。

編集:@Evynの回答から このリンク をたどると、このjavascript/jqueryコードが機能します。

var lastTouchY = 0;
var preventPullToRefresh = false;

$('body').on('touchstart', function (e) {
    if (e.originalEvent.touches.length != 1) { return; }
    lastTouchY = e.originalEvent.touches[0].clientY;
    preventPullToRefresh = window.pageYOffset == 0;
});

$('body').on('touchmove', function (e) {
    var touchY = e.originalEvent.touches[0].clientY;
    var touchYDelta = touchY - lastTouchY;
    lastTouchY = touchY;
    if (preventPullToRefresh) {
        // To suppress pull-to-refresh it is sufficient to preventDefault the first overscrolling touchmove.
        preventPullToRefresh = false;
        if (touchYDelta > 0) {
            e.preventDefault();
            return;
        }
    }
});

@bcintegrityが指摘したように、将来的にはサイトマニフェストソリューション(および/またはメタタグ)を期待しています。

さらに、上記のコードに関する提案を歓迎します。

119
Sebastiano

プルツーリフレッシュエフェクトのデフォルトアクションは、次のいずれかを実行することで効果的に防止できます。

  1. 以下のいずれかを含む、タッチシーケンスの一部をpreventDefault(最も破壊的なものから破壊的なものの順に):
    • a。タッチストリーム全体(理想的ではありません)。
    • b。すべてのトップオーバースクロールタッチムーブ。
    • c。最初の上部スクロールタッチムーブ。
    • d。最初のトップオーバースクロールタッチムーブは、1)ページyスクロールオフセットがゼロのときに最初のタッチスタートが発生し、2)タッチムーブがトップオーバースクロールを引き起こした場合にのみ行われます。
  2. touch-action: none」をタッチターゲット要素に適用し、必要に応じて、タッチシーケンスのデフォルトアクション(プルトゥリフレッシュを含む)を無効にします。
  3. Body要素に「overflow-y: hidden」を適用し、必要に応じてスクロール可能なコンテンツにdivを使用します。
  4. chrome://flags/#disable-pull-to-refresh-effectを介してローカルでエフェクトを無効にします。

詳細を参照

139
Evyn

2018+向けのシンプルなソリューション

Chrome 63(2017年12月5日リリース)は、これを正確に支援するcssプロパティを追加しました。 Googleのこのガイド を読んで、それをどのように処理できるかをよく理解してください。

TL:DRはここにあります

CSSのoverscroll-behaviorプロパティを使用すると、開発者はコンテンツの最上部/最下部に到達したときにブラウザーのデフォルトのオーバーフロースクロール動作をオーバーライドできます。ユースケースには、モバイルでのプルトゥリフレッシュ機能の無効化、オーバースクロールグローとラバーバンディング効果の削除、モーダル/オーバーレイの下にあるページコンテンツのスクロール防止などがあります。

動作させるには、CSSに以下を追加するだけです。

body {
  overscroll-behavior: contain;
}

また、現時点ではChrome、Edge、Firefoxで サポート のみですが、Safariはサービスワーカーと将来のPWAが完全に搭載されているように見えるので、すぐに追加されると確信しています。

68
Matthew Mullin

現時点では、この機能を無効にできるのは chrome:// flags /#disable-pull-to-refresh-effect -デバイスから直接開くだけです。

touchmoveイベントをキャッチしようとすることもできますが、許容可能な結果を​​達成する可能性は非常にわずかです。

15
Kevin Busse

MooToolsを使用し、ターゲット要素の更新を無効にするクラスを作成しましたが、その核心は(ネイティブJS)です。

var target = window; // this can be any scrollable element
var last_y = 0;
target.addEventListener('touchmove', function(e){
    var scrolly = target.pageYOffset || target.scrollTop || 0;
    var direction = e.changedTouches[0].pageY > last_y ? 1 : -1;
    if(direction>0 && scrolly===0){
        e.preventDefault();
    }
    last_y = e.changedTouches[0].pageY;
});

ここで行うことは、タッチムーブのy方向を見つけることだけです。画面を下に移動し、ターゲットスクロールが0の場合、イベントを停止します。したがって、更新はありません。

これは、すべての「移動」で発砲することを意味しますが、これは高価になる可能性がありますが、私がこれまでに見つけた最良の解決策です...

8
Eclectic

何時間も試してみた後、このソリューションは私のために機能します

$("html").css({
    "touch-action": "pan-down"
});
5
José Loguercio

AngularJS

私はこのAngularJSディレクティブでそれを正常に無効にしました:

//Prevents "pull to reload" behaviour in Chrome. Assign to child scrollable elements.
angular.module('hereApp.directive').directive('noPullToReload', function() {
    'use strict';

    return {
        link: function(scope, element) {
            var initialY = null,
                previousY = null,
                bindScrollEvent = function(e){
                    previousY = initialY = e.touches[0].clientY;

                    // Pull to reload won't be activated if the element is not initially at scrollTop === 0
                    if(element[0].scrollTop <= 0){
                        element.on("touchmove", blockScroll);
                    }
                },
                blockScroll = function(e){
                    if(previousY && previousY < e.touches[0].clientY){ //Scrolling up
                        e.preventDefault();
                    }
                    else if(initialY >= e.touches[0].clientY){ //Scrolling down
                        //As soon as you scroll down, there is no risk of pulling to reload
                        element.off("touchmove", blockScroll);
                    }
                    previousY = e.touches[0].clientY;
                },
                unbindScrollEvent = function(e){
                    element.off("touchmove", blockScroll);
                };
            element.on("touchstart", bindScrollEvent);
            element.on("touchend", unbindScrollEvent);
        }
    };
});

リフレッシュするためのプルはトリガーされる可能性がないため、ユーザーがスクロールダウンするとすぐに視聴を停止しても安全です。

同様に、scrolltop > 0の場合、イベントはトリガーされません。私の実装では、scrollTop <= 0の場合にのみ、touchstartでtouchmoveイベントをバインドします。ユーザーが下にスクロールするとすぐにバインドを解除します(initialY >= e.touches[0].clientY)。ユーザーが上にスクロールすると(previousY < e.touches[0].clientY)、preventDefault()を呼び出します。

これにより、スクロールイベントを不必要に監視する必要がなくなり、オーバースクロールがブロックされます。

jQuery

JQueryを使用している場合、これは未テストと同等です。 elementはjQuery要素です。

var initialY = null,
    previousY = null,
    bindScrollEvent = function(e){
        previousY = initialY = e.touches[0].clientY;

        // Pull to reload won't be activated if the element is not initially at scrollTop === 0
        if(element[0].scrollTop <= 0){
            element.on("touchmove", blockScroll);
        }
    },
    blockScroll = function(e){
        if(previousY && previousY < e.touches[0].clientY){ //Scrolling up
            e.preventDefault();
        }
        else if(initialY >= e.touches[0].clientY){ //Scrolling down
            //As soon as you scroll down, there is no risk of pulling to reload
            element.off("touchmove");
        }
        previousY = e.touches[0].clientY;
    },
    unbindScrollEvent = function(e){
        element.off("touchmove");
    };
element.on("touchstart", bindScrollEvent);
element.on("touchend", unbindScrollEvent);

当然、純粋なJSでも同じことが実現できます。

5

シンプルなJavascript

標準のJavaScriptを使用して実装しました。シンプルで簡単に実装できます。貼り付けるだけで問題なく動作します。

<script type="text/javascript">         //<![CDATA[
     window.addEventListener('load', function() {
          var maybePreventPullToRefresh = false;
          var lastTouchY = 0;
          var touchstartHandler = function(e) {
            if (e.touches.length != 1) return;
            lastTouchY = e.touches[0].clientY;
            // Pull-to-refresh will only trigger if the scroll begins when the
            // document's Y offset is zero.
            maybePreventPullToRefresh =
                window.pageYOffset == 0;
          }

          var touchmoveHandler = function(e) {
            var touchY = e.touches[0].clientY;
            var touchYDelta = touchY - lastTouchY;
            lastTouchY = touchY;

            if (maybePreventPullToRefresh) {
              // To suppress pull-to-refresh it is sufficient to preventDefault the
              // first overscrolling touchmove.
              maybePreventPullToRefresh = false;
              if (touchYDelta > 0) {
                e.preventDefault();
                return;
              }
            }
          }

          document.addEventListener('touchstart', touchstartHandler, false);
          document.addEventListener('touchmove', touchmoveHandler, false);      });
            //]]>    </script>
4
Sacky San

純粋なCSSの最適なソリューション:

body {
    width: 100%;
    height: 100%;
    display: block;
    position: absolute;
    top: -1px;
    z-index: 1;
    margin: 0;
    padding: 0;
    overflow-y: hidden;
}
#pseudobody {
    width:100%;
    height: 100%;
    position: absolute;
    top:0;
    z-index: 2;
    margin: 0;
    padding:0;
    overflow-y: auto;
}

このデモを参照してください: https://jsbin.com/pokusideha/quiet

3
Eugene Fox

あなたの設定を見つけます  CSS オーバーフローy:非表示 最も簡単な方法です。スクロールアプリケーションページが必要な場合は、スクロール機能を備えたdivコンテナを使用できます。

3
Keegan Teetaert

数週間後、Chrome更新アクションを無効にするために使用したjavascript関数が機能しなくなることがわかりました。私はそれを解決するためにこれを作りました:

$(window).scroll(function() {
   if ($(document).scrollTop() >= 1) {
      $("html").css({
         "touch-action": "auto"}
      );
   } else {
      $("html").css({
         "touch-action": "pan-down"
      });
   }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
2
Wobbo

Overflow-yは継承されないため、すべてのブロック要素に設定する必要があることに注意してください。

次の方法でjQueryを使用してこれを行うことができます。

        $(document.body).css('overflow-y', 'hidden'); 
        $('*').filter(function(index) {
            return $(this).css('display') == 'block';
        }).css('overflow-y', 'hidden');
1
kofifus

純粋なjsソリューション。

// Prevent pull refresh chrome
    var lastTouchY = 0;
    var preventPullToRefresh = false;
    window.document.body.addEventListener("touchstart", function(e){
        if (e.touches.length != 1) { return; }
        lastTouchY = e.touches[0].clientY;
        preventPullToRefresh = window.pageYOffset == 0;
    }, false);

    window.document.body.addEventListener("touchmove", function(e){

        var touchY = e.touches[0].clientY;
        var touchYDelta = touchY - lastTouchY;
        lastTouchY = touchY;
        if (preventPullToRefresh) {
            // To suppress pull-to-refresh it is sufficient to preventDefault the first overscrolling touchmove.
            preventPullToRefresh = false;
            if (touchYDelta > 0) {
                e.preventDefault();
                return;
            }
        }

    }, false);
0
user1503606

私がしたことは、touchstartおよびtouchend/touchcancelイベントに以下を追加することでした:

scrollTo(0, 1)

chromeがscrollY位置にない場合はスクロールしないので、0はchromeがプルしてリフレッシュするのを防ぎます。

それでも機能しない場合は、ページが読み込まれたときにもそれを試してください。

0
xdevs23

私はこれでプルダウンからリフレッシュの問題を解決しました:

html, body {
    width: 100%;
    height: 100%;
    overflow: hidden;
}
0
Paul Iştoan