it-swarm.com.de

Deaktivieren Sie die Chrome-Pulldown-Funktion zum Aktualisieren von Android

Ich habe eine kleine HTML5-Webanwendung für mein Unternehmen erstellt.

Diese Anwendung zeigt eine Liste der Elemente an und alles funktioniert gut.

Die Anwendung wird hauptsächlich auf Android-Handys und Chrome als Browser verwendet. Außerdem wird die Site auf dem Startbildschirm gespeichert, sodass Android das Ganze als App verwaltet (mit einem WebView, denke ich).

Chrom Beta (und ich denke auch das Android System WebView) hat eine "Pulldown to Refresh" -Funktion eingeführt ( Siehe diesen Link zum Beispiel ). 

Dies ist eine praktische Funktion, aber ich habe mich gefragt, ob sie mit einigen Metatags (oder Javascript-Elementen) deaktiviert werden kann, da die Aktualisierung vom Benutzer beim Navigieren der Liste leicht ausgelöst werden kann und die gesamte App neu geladen wird.

Auch diese Funktion wird von der Anwendung nicht benötigt.

Ich weiß, dass diese Funktion nur in Chrome Beta verfügbar ist, aber ich habe das Gefühl, dass dies auch auf der stabilen App landet.

Vielen Dank!

Bearbeiten: Ich habe Chrome Beta deinstalliert und der Link auf dem Startbildschirm wird jetzt mit dem stabilen Chrome geöffnet. Die gepinnten Links beginnen also mit Chrome und nicht mit einem Webview.

Edit: Heute (2015-03-19) ist das Pulldown zum Aktualisieren zum stabilen Chrom gekommen.

Edit: von @Evyn antworte ich diesem Link und habe diesen Javascript/jquery-Code erhalten, der funktioniert.

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;
        }
    }
});

Wie @bcintegrity darauf hinweist, hoffe ich auf eine Site-Manifest-Lösung (und/oder ein Meta-Tag) in der Zukunft.

Darüber hinaus sind Vorschläge für den obigen Code willkommen.

114
Sebastiano

Die Standardaktion des Pull-to-Refresh-Effekts kann auf folgende Weise wirksam verhindert werden:

  1. preventDefault ’einen Teil der Berührungssequenz, einschließlich der folgenden (in der Reihenfolge der störendsten bis am wenigsten störenden):
    • ein. Der gesamte Touch-Stream (nicht ideal).
    • b. Alle Top-Overcrolling-Touchmoves.
    • c. Der erste Top-Overcrolling-Touchmove.
    • d. Der erste Top-Overcrolling-Touch-Move nur dann, wenn 1) der anfängliche Touchstart auftrat, als der Seiten-y-Scroll-Offset Null war und 2) der Touch-Move einen Top-Overscroll auslösen würde.
  2. Anwenden von "touch-action: none" auf berührungsbezogene Elemente, gegebenenfalls Deaktivieren der Standardaktionen (einschließlich Pull-to-Refresh) der Berührungssequenz.
  3. Anwenden von "overflow-y: hidden" auf das body-Element und ggf. ein div für scrollbaren Inhalt.
  4. Deaktivieren Sie den Effekt lokal über chrome://flags/#disable-pull-to-refresh-effect).

Mehr sehen

136
Evyn

Einfache Lösung für 2018+

Chrome 63 (veröffentlicht am 5. Dezember 2017) hat eine CSS-Eigenschaft hinzugefügt, mit der genau dies unterstützt werden kann. Lesen Sie durch dieses Handbuch von Google , um eine gute Vorstellung davon zu bekommen, wie Sie damit umgehen können. 

Hier ist ihr TL: DR

Mit der CSS-Eigenschaft "overscroll-behaviour" können Entwickler die .__ überschreiben. Browser-Standard-Überlauf-Scrollverhalten beim Erreichen von oben/unten inhalt. Anwendungsfälle umfassen das Deaktivieren des Pull-to-Refresh Funktion auf dem Handy, Entfernen von Glühen mit Überlauf und Gummibandeffekten, und das Blättern des Seiteninhalts unter einem modal/überlagert.

Damit es funktioniert, müssen Sie nur Folgendes in Ihrem CSS hinzufügen:

body {
  overscroll-behavior: contain;
}

Es ist vorerst auch nur unterstützt von Chrome, Edge und Firefox, aber ich bin mir sicher, dass Safari es bald hinzufügen wird, sobald sie voll mit Service-Mitarbeitern und der Zukunft von PWA verbunden sind.

53
Matthew Mullin

Im Moment können Sie diese Funktion nur über chrome: // flags/# disable-pull-to-refresh-effect - direkt von Ihrem Gerät aus deaktivieren.

Sie könnten versuchen, touchmove-Ereignisse abzufangen, aber die Chancen sind sehr gering, ein akzeptables Ergebnis zu erzielen.

15
Kevin Busse

Ich verwende MooTools und habe eine Klasse zum Deaktivieren der Aktualisierung für ein Zielelement erstellt. Der Kernpunkt ist jedoch (native 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;
});

Alles, was wir hier tun, ist die y-Richtung des Touchmoves zu finden, und wenn wir uns auf dem Bildschirm nach unten bewegen und die Zielrolle 0 ist, stoppen wir das Ereignis. Also keine Auffrischung.

Dies bedeutet, dass wir auf jeden "Zug" schießen, was teuer sein kann, aber die beste Lösung, die ich bisher gefunden habe ...

8
Eclectic

Nach vielen Stunden des Versuchens funktioniert diese Lösung für mich

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

AngularJS

Ich habe es mit dieser AngularJS-Direktive erfolgreich deaktiviert:

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

Es ist sicher, die Wiedergabe anzuhalten, sobald der Benutzer einen Bildlauf nach unten ausgeführt hat, da beim Ziehen zum Aktualisieren keine Chance besteht, ausgelöst zu werden.

Bei scrolltop > 0 wird das Ereignis ebenfalls nicht ausgelöst. In meiner Implementierung binde ich das touchmove -Ereignis bei touchstart nur, wenn scrollTop <= 0. Ich löse es, sobald der Benutzer nach unten scrollen (initialY >= e.touches[0].clientY). Wenn der Benutzer nach oben blättert (previousY < e.touches[0].clientY), rufe ich preventDefault() auf.

Dies erspart uns das unnötige Anschauen von Scroll-Ereignissen, blockiert jedoch das Überscrollen.

jQuery

Wenn Sie jQuery verwenden, ist dies das ungetestete - Äquivalent. element ist ein jQuery-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");
        }
        previousY = e.touches[0].clientY;
    },
    unbindScrollEvent = function(e){
        element.off("touchmove");
    };
element.on("touchstart", bindScrollEvent);
element.on("touchend", unbindScrollEvent);

Dasselbe kann natürlich auch mit pure JS erreicht werden.

5

Einfaches Javascript

Ich habe mit Standard-Javascript implementiert. Einfach und leicht zu implementieren. Einfach einfügen und es funktioniert gut.

<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

Die beste Lösung für reines 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;
}

Sehen Sie sich diese Demo an: https://jsbin.com/pokusideha/quiet

4
Eugene Fox

Ich finde deine Einstellung karosserie CSS Überlauf-y: versteckt ist der einfachste Weg. Wenn Sie eine Scroll-Anwendungsseite haben möchten, können Sie einfach einen Div-Container mit Scroll-Funktionen verwenden. 

3
Keegan Teetaert

Seit einigen Wochen habe ich herausgefunden, dass die Javascript-Funktion, mit der ich die Chrome-Aktualisierungsaktion deaktiviert habe, nicht mehr funktioniert. Ich habe das gemacht, um es zu lösen: 

$(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

Beachten Sie, dass overflow-y nicht vererbt wird. Sie müssen es also auf ALLE Blockelemente setzen.

Sie können dies mit jQuery einfach durch:

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

Reine js Lösung.

// 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

Was ich getan habe, war folgendes zu den touchstart- und touchend/touchcancel-Ereignissen hinzuzufügen:

scrollTo(0, 1)

Da Chrome nicht scrollt, wenn es sich nicht in der ScrollY-Position 0 befindet, wird Chrome nicht zum Aktualisieren ziehen.

Wenn es immer noch nicht funktioniert, versuchen Sie es auch beim Laden der Seite.

0
xdevs23

Ich habe das Pull-Down-To-Refresh-Problem folgendermaßen gelöst:

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