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


135

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

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

このアプリケーションは、主にAndroidフォンとブラウザとしてChromeで使用されます。また、サイトはホーム画面に保存されるので、Androidはアプリ全体を(おそらくWebViewを使用して)アプリとして管理します。

Chrome ベータ(そして私はAndroidシステムWebViewもそうだと思います)は「プルダウンして更新」機能を導入しました(このリンクを例に見てください)。

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

また、これはアプリケーションに不要な機能です。

この機能がまだChromeベータ版でのみ利用可能であることは知っていますが、これも安定したアプリに搭載されているという感覚を持っています。

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

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

編集:本日(2015-03-19)プルダウンからリフレッシュへの安定したクロームが登場しました。

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

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

さらに、上記のコードの提案は大歓迎です。


18
ええ、これは本当に最悪です。フォームの中央にあり、上にスクロールしすぎたため、更新されてすべてが失われました。これは遅延されたデフォルト機能です。更新したい場合は、[更新]アイコンをクリックします。
Brock Hensley

12
この機能を私のWebアプリマニフェストで無効にできると便利です。残念ながら、私のWebアプリのすべてのページにはスクロール可能なコンテンツがあり、更新せずに移動することはほとんど不可能です。私は少しカチカチしています。:/
bcintegrity 2015年

これは良い情報です。プルトゥリフレッシュ機能を無効にするWebサイトは嫌いです。ページのコンテンツに関係なく更新が機能する機能を開発したいと思います。
LS

5
Web開発者と言えば、プルダウンリフレッシュはアプリケーションをリロードするため、データ駆動型Webサイトと互換性がありません。ユーザーがページ全体を更新せずにページの上部にスクロールすることは不可能です。私はChromeを100%支持しています。このアンチ機能が削除されることを願っています。
2016年

3
私はこのGCの「機能」に直面しました...たくさんのWebページ、多くのフォーム、指で不注意にプルダウンすると、このページのデータは失われます!リタード機能IMO。それはデフォルトでオフになっている必要があり、それを必要とする人はそれをコーディングすることができます。「クライアント」がGCで時々データを失った理由を何日か知りました...
Ludus H

回答:


157

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

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

続きを見る


12
@Evynありがとうございます。これは簡単な修正であるとは思えません!body要素のCSSをoverflow-y:hiddenに設定しました。
bcintegrity 2015年

@Evynに感謝し、preventDefault()メソッドを使用することにしました(最初のポイント)。特に、リンクしたドキュメント内にあるリンク(link)のソースコードが興味深いことに気づきました。質問の最後にコードを追加します。
Sebastiano

2
"chrome:// flags(disable-pull-to-refresh-effect)"はプログラムでどのように行われますか?
誰かどこか

2
@SomeoneSomeone私の知る限り、それは不可能ではありません。Chromeの設定はユーザーのみが設定できます。そうしないとセキュリティリスクが発生します
Mike

1
「overflow-y:hidden」をbody要素に適用し、スクロール可能なコンテンツにdivを使用するとうまくいきました。
ロビン

103

2019+のシンプルなソリューション

Chrome 63は、まさにこれを手助けするためにcssプロパティを追加しました。Googleこのガイドを読んで、それをどのように処理できるかをよく理解してください。

これがTL:DRです。

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

これを機能させるには、CSSに次のコードを追加するだけです。

body {
  overscroll-behavior: contain;
}

現在のところ、Chrome、Edge、Firefoxでのみサポートされていますが、サービスワーカーとPWAの将来に完全に対応していると思われるため、Safariですぐに追加されると思います。


16
これは最新のアンサー
colxi

「ホーム画面に追加」クロームバナーの表示が遅れていることに他の誰かが気付いたことがありますか?
ナサニエルヒル

2
無効にするためにhtml要素に適用する必要がありました
Jakob Eriksson

1
この作品はAndroidのみ、
IOs


15

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

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


1
回答をありがとうケビン。ユーザーに依存しないものを探していたので、これを受け入れられたものとして受け入れることができませんでした。ただし、この方法は機能するので、十分な評判が得られたら、私はあなたの回答を賛成します。
Sebastiano

残念ですが、これが最善の解決策のようです-そのフラグの設定が将来変更される場合、または他のサイトでプルを使用して更新できるようにしたい場合...これはプログラムで制御できないことに驚いています。:(。
user1063287

1
GoogleのCEOがこれを読んでいる場合は、この機能を削除してください。簡単かつ包括的に無効にできるとは思われません。私の意見では、すべてのWebアプリケーションが必要とするわけではないWebアプリケーションの「機能」です。
user1063287 2017年

8

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の場合、イベントを停止します。したがって、更新はありません。

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


2
プルトゥリフレッシュはトリガーされる可能性がないため、ユーザーが下にスクロールするとすぐに視聴を停止しても安全です。同様に、の場合scrolltop > 0、イベントはトリガーされません。私の実装では、にのみtouchmoveイベントをバインドします。ユーザーが下にスクロールするとすぐに、バインドを解除します()。ユーザーが上にスクロールすると()、次にを呼び出します。touchstartscrollTop <= 0initialY >= e.touches[0].clientYpreviousY < e.touches[0].clientYpreventDefault
Nicolas Bouliane 2015

7

何時間も試した後、この解決策は私にとってうまくいきます

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

このためにjQueryを使用する必要はありません。"touch-action:pan-down"をcssコードファイルに追加するだけです。
キーガンTeetaert

1
これをCSSで使用してください:html{touch-action:pan-down}
csandreas1

5

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

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

jQuery

jQueryを使用している場合、これはテストされていない同等のものです。elementjQuery要素です。

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でも同じことが実現できます。


私はe.originalEvent.touches[0].clientYこの仕事をするために使用しなければなりませんでした。リロードを防ぐタイミングはまだロジックと苦労しています。今のところ、ランダムに上にスクロールできないようです...正しい方向へのヒントに感謝します!
トーマス2015年

ディレクティブはどの要素に追加されますか?
Fizzix、2016

AngularJSディレクティブはうまく機能しました。私たちはFramework7とAngularを一緒に使用しており(推奨しません)、scrollTopの正しい動作をブロックしているものがあります。そのため、blockScrollが要素に追加されるタイミングを変更する必要がありました。しかし、感謝の気持ちを伝えたかっただけです。
ダスティンジェンセン

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>

これはChromeでは非常にうまく機能しましたが、ページの上部にあるdivをスクロールすると、Safari / iOS 9.2で上にスクロールすると問題が発生しました(ここで再現)。私は上のEvynbody: {overflow-y:hidden}からのトリックを使用してしまいました。
sennett 2016年

Chromeで動作しますが、Firefoxの例の作品はありませんようdownvoting、embed.plnkr.co/rqbOVSOkKyhAgoHK2sEP 唯一のモバイルで開く
ビジェイ

貼り付けたリンクは、私のAndroidモバイルでもChromeで機能しました。プル時にリフレッシュすることはできませんでした。テストに使用しているandroid / iosのバージョンは何ですか?
Sacky San、2017

2
Chrome 56以降では、機能させるためにpassive:falseを設定する必要があります。document.addEventListener( 'touchstart'、touchstartHandler、{passive:false}); document.addEventListener( 'touchmove'、touchmoveHandler、{passive:false});
アントンクズミン2017年

4

純粋な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


あなたは本当にこれをクロムを使った携帯電話でテストしましたか?
Gregor Voinov


3

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


ラインで修正することは不可能のようですが、魅力のように機能します。
イグナシオアラ

2

ただし、overflow-yは継承されないため、すべてのブロック要素に設定する必要があります。

jQueryでこれを行うには、次のようにします。

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

他の答えの中で、これは本当に役立ちます。ありがとう。この行をcssに追加します。body {overflow-y:hidden; }
サリンJS

2

数週間前から、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>


1

純粋な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

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

scrollTo(0, 1)

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

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


0

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

html, body {
    width: 100%;
    height: 100%;
    overflow: hidden;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.