Android'in krom açılır-yenilemek özelliğini devre dışı bırakma


135

Şirketim için küçük bir HTML5 web uygulaması oluşturdum.

Bu uygulama öğelerin bir listesini görüntüler ve her şey iyi çalışıyor.

Uygulama esas olarak tarayıcı olarak android telefonlarda ve Chrome'da kullanılır. Ayrıca, site ana ekrana kaydedilir, böylece Android her şeyi bir uygulama olarak yönetir ( sanırım bir WebView kullanarak ).

Chrome Beta (ve ayrıca Android Sistem WebView) "yenilemek için aşağı çek" özelliğini de tanıttı ( örneğin bu bağlantıya bakın ).

Bu kullanışlı bir özellik ama bazı meta etiketi (veya javascript şeyler) ile devre dışı bırakılabilir olup olmadığını merak ediyordum çünkü yenileme listede gezinirken kullanıcı tarafından kolayca tetiklenebilir ve tüm uygulama yeniden yüklenir.

Ayrıca bu uygulama tarafından gerekli olmayan bir özelliktir.

Bu özelliğin yalnızca Chrome beta sürümünde hala mevcut olduğunu biliyorum, ancak bunun kararlı uygulamaya da indiği hissine sahibim.

Teşekkür ederim!

Düzenleme: Chrome Beta'yı kaldırdım ve ana ekrana sabitlenmiş bağlantı artık kararlı Chrome ile açılıyor. Dolayısıyla, sabitlenmiş bağlantılar web görünümü ile değil Chrome ile başlar.

Düzenleme: bugün (2015-03-19) yenilemek için aşağı çekme istikrarlı krom geldi.

Düzenleme: @Evyn cevap Bu bağlantıyı takip ve çalışan bu javascript / jquery kodu var.

@Bcintegrity'nin işaret ettiği gibi, gelecekte bir site bildirim çözümü (ve / veya bir meta-etiket) umarım.

Ayrıca, yukarıdaki kod için öneriler memnuniyetle karşılanmaktadır.


18
Evet bu gerçekten berbat. Formun ortasında oldu ve çok üstte kaydırdı ve yenilenir ve her şeyi kaybetti. Bu geciktirilmiş bir varsayılan özelliktir, yenilemek istiyorsam Yenile simgesini tıklıyorum!
Brock Hensley

12
Bu özellik web uygulaması bildirimimde devre dışı bırakılabilirse iyi olur. Ne yazık ki, web uygulamamdaki her sayfa kaydırılabilir içeriğe sahip, yenilenmeden gezinmeyi neredeyse imkansız hale getiriyor. Biraz işaretliyim. : /
bcintegrity

Bu iyi bir bilgi. Yenileme için çekme özelliğini devre dışı bırakan web sitelerinden nefret ediyorum. Sayfa içeriğinden bağımsız olarak yenilemenin çalışması için bir özellik geliştirmek istiyorum.
LS

5
Bir web geliştiricisi olarak konuşan açılan yenileme, uygulamayı yeniden yüklediği için veri odaklı web siteleriyle uyumsuzdur. Kullanıcının tüm sayfayı yenilemeden sayfanın üstüne gitmesini imkansız hale getirir. Chrome'u% 100 destekliyorum, umarım bu anti-özelliği kaldırırlar.
Fasulye

3
Kendimi bu GC "özelliği" ile karşı karşıya kaldım ... bol web sayfası, birçok form, parmağımla dikkatsiz bir aşağı çekin ve bu sayfadaki veriler kayboluyor! Geciktirme fonksiyonu IMO. Kimin daha sonra kodlamasına izin vermesi gerekiyorsa, varsayılan olarak kapalı olmalıdır. "Müşterilerimin"
GC'deki

Yanıtlar:


157

Yenileme için çekme efektinin varsayılan eylemi, aşağıdakilerden herhangi biri yapılarak etkili bir şekilde önlenebilir:

  1. preventDefaultAşağıdakilerden herhangi biri dahil olmak üzere dokunma dizisinin bir kısmını (en yıkıcı ila en az yıkıcı sırayla):
    • a. Tüm dokunmatik akış (ideal değil).
    • b. Tüm üst düzey kaydırmalı dokunmatik ekranlar.
    • c. En üstteki ilk fazla kaydırmalı dokunmatik ekran.
    • d. İlk üst aşırı kaydırmalı dokunmatik ekran yalnızca 1) ilk dokunmatik başlangıç, sayfa y kaydırma ofseti sıfır olduğunda ve 2) dokunmatik ekran üst aşırı kaydırmaya neden olduğunda meydana gelir.
  2. touch-action: noneDokunma hedefli öğelere “ ” uygulamak , uygun olduğunda, dokunma dizisinin varsayılan eylemlerini (yenilemek için çekme dahil) devre dışı bırakmak.
  3. overflow-y: hiddenGövde elemanına “ ” uygulamak , gerekirse kaydırılabilir içerik için bir div kullanmak.
  4. Üzerinden efekti yerel olarak devre dışı bırakma chrome://flags/#disable-pull-to-refresh-effect ).

Daha fazla gör


12
Teşekkürler @Evyn. Bunun hızlı bir düzeltme olduğuna inanamıyorum! Gövde öğesinin CSS'sini taşma-y: gizli olarak ayarladım.
bcintegrity

Teşekkürler @Evyn, preventDefault () yöntemini (ilk nokta) kullanmaya karar verdim. Özellikle , bağladığınız belgenin içindeki bağlantının ( bağlantı ) kaynak kodunu ilginç buldum . Kodu sorumun sonuna koyacağım.
Sebastiano

2
"chrome: // flags (devre dışı bırak-yenilemek-efekti)" programlı olarak nasıl yapılır?
Bir Yerde

2
Bildiğim kadarıyla bir yerlerde, bu imkansız değil. krom ayarları yalnızca kullanıcı tarafından ayarlanabilir - aksi takdirde güvenlik riski oluşturur
Mike

1
Gövde öğesine "overflow-y: hidden" uygulamak, kaydırılabilir içerik için bir div kullanmak benim için çalıştı.
Robin

105

2019+ için basit çözüm

Chrome 63, tam olarak buna yardımcı olmak için bir css özelliği ekledi. Google ile nasıl başa çıkabileceğiniz konusunda iyi bir fikir edinmek için bu kılavuzu okuyun .

İşte TL: DR

CSS aşırı kaydırma davranışı özelliği, geliştiricilerin içeriğin üstüne / altına ulaşırken tarayıcının varsayılan taşma kaydırma davranışını geçersiz kılmasına olanak tanır. Kullanım durumları arasında mobil cihazlarda yenileme-yenileme özelliğini devre dışı bırakma, aşırı kaydırma ışıma ve lastik bantlama efektlerini kaldırma ve kalıcı / yer paylaşımının altındayken sayfa içeriğinin kaymasını önleme sayılabilir.

Çalıştırmak için eklemeniz gereken tek şey CSS'nizde:

body {
  overscroll-behavior: contain;
}

Şimdilik yalnızca Chrome, Edge ve Firefox tarafından da destekleniyor , ancak eminim Safari, servis çalışanları ve PWA'ların geleceği ile tamamen uyumlu olduklarında yakında ekleyecek.


16
Bu en güncel anwser
colxi

Başkasının "Ana Ekrana Ekle" krom şeridinin görünmesini geciktirdiğini fark eden var mı?
Nathaniel Hill

2
devre dışı bırakmak için html elemanına uygulamak zorunda kaldı
Jakob Eriksson

1
Bu sadece Android,
IOs


15

Şu anda bu özelliği yalnızca chrome: // flags / # enable-pull-to-refresh-effect - doğrudan cihazınızdan açarak devre dışı bırakabilirsiniz .

touchmoveOlayları yakalamayı deneyebilirsiniz , ancak kabul edilebilir bir sonuç elde etme şansı çok düşüktür.


1
Cevabınız için teşekkür ederim Kevin. Bunu kabul edilen olarak kabul edemedim çünkü kullanıcılardan bağımlı olmayan bir şey arıyordum. Ancak bu yöntem işe yarıyor, bu yüzden yeterince itibar kazandıkça cevabınızı onaylayacağım.
Sebastiano

Bu en iyi çözüm gibi görünüyor üzücü - bu bayrak ayarı gelecekte değişirse veya diğer sitelerde yenilemek için çekme özelliğini kullanmak istiyorsanız ... Bunun programlı olarak kontrol edilememesi şaşırtıcıydı. :(.
user1063287

1
Google CEO'su bunu okuyorsa, lütfen bu özelliği kaldırın. Kolay ve kapsamlı bir şekilde devre dışı bırakılabileceği görülmüyor ve bence tüm web uygulamalarının istemediği bir web uygulaması "özelliği".
user1063287

8

MooTools kullanın ve hedeflenen bir öğe üzerinde yenilemeyi devre dışı bırakmak için bir sınıf oluşturduk, ancak bunun temel noktası (yerli 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;
});

Burada yaptığımız tek şey, dokunma hareketinin y yönünü bulmaktır ve eğer ekranı aşağı hareket ettirirsek ve hedef kaydırma 0 ise, olayı durdururuz. Böylece, yenileme yok.

Bu, pahalı olabilen her 'harekete' ateş ettiğimiz anlamına geliyor, ancak şu ana kadar bulduğum en iyi çözüm ...


2
Kullanıcı aşağı iner inmez izlemeyi durdurmak güvenlidir, çünkü yenilemek için çekme işleminin tetiklenme şansı yoktur. Aynı şekilde, scrolltop > 0olay tetiklenmezse. Uygulamamda, touchmoveolayı touchstartsadece eğer scrollTop <= 0. Kullanıcı aşağı kaydırır kaydırmaz ( initialY >= e.touches[0].clientY). Kullanıcı yukarı kaydırırsa ( previousY < e.touches[0].clientY), o zaman ararım preventDefault.
Nicolas Bouliane

7

Saatlerce denedikten sonra, bu çözüm benim için çalışıyor

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

Bunun için jQuery kullanmaya gerek yoktur. Sadece "touch-action: aşağı kaydır" ı css kod dosyanıza eklemeniz yeterlidir.
Keegan Teetaert

1
sadece html{touch-action:pan-down}
css'nizde

5

angularjs

Bu AngularJS yönergesi ile başarıyla devre dışı bıraktım:

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

Kullanıcı aşağı iner inmez izlemeyi durdurmak güvenlidir, çünkü yenilemek için çekme işleminin tetiklenme şansı yoktur.

Aynı şekilde, scrolltop > 0olay tetiklenmezse. Uygulamamda, touchmove olayında touchmove olayını sadece eğer scrollTop <= 0. Kullanıcı aşağı kaydırır kaydırmaz ( initialY >= e.touches[0].clientY). Kullanıcı yukarı kaydırırsa ( previousY < e.touches[0].clientY), o zaman ararım preventDefault().

Bu, kaydırma olaylarını gereksiz yere izlememizi sağlar, ancak fazla kaydırmayı engeller.

jQuery

JQuery kullanıyorsanız, bu test edilmemiş eşdeğerdir. elementbir jQuery öğesidir:

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

Doğal olarak, aynı şey saf JS ile de elde edilebilir.


e.originalEvent.touches[0].clientYBu işi yapmak için kullanmak zorunda kaldım . Ne zaman yeniden yüklemeyi önlemek için mantık ile mücadele . Şu anda rastgele yukarı kaydırmayı engelliyor gibi görünüyor ... İpucu için doğru yönde teşekkürler!
thomas

Yönerge hangi öğeye eklenir?
Fizzix

AngularJS direktifi benim için iyi çalıştı. Framework7 ve Angular'ı birlikte kullanıyoruz (bunu önermiyoruz) ve scrollTop'un doğru davranışını engelleyen bir şey vardı. Bu yüzden elemente blockScroll ekleneceği zaman değiştirmek zorunda kaldım. Ama sadece teşekkür etmek istedim!
Dustin Jensen

5

Basit Javascript

Standart javascript kullanarak uyguladım. Basit ve kolay uygulanır. Sadece yapıştırın ve iyi çalışıyor.

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

Bu Chrome için çok iyi çalıştı, ancak sayfanın üst kısmında bir div kaydırırken ( burada çoğaltılır ) Safari / iOS 9.2'de benim için yukarı kaydırmayla ilgili bazı sorunlara neden oldu . Yukarıda Evyn'inbody: {overflow-y:hidden} numaralarını kullandım .
sennett

krom üzerinde çalışmıyor, ancak firefox örneğinde çalışıyor, embed.plnkr.co/rqbOVSOkKyhAgoHK2sEP SADECE MOBİLDE açık
vijay

Yapıştırdığınız bağlantı, Android cep telefonumda da kromda çalıştı. çekerek yenilemeye izin vermedi. test etmek için android / ios'un hangi sürümünü kullanıyorsunuz?
Sacky San

2
Chrome 56'dan çalışması için pasif: false ayarlamanız gerekir: document.addEventListener ('touchstart', touchstartHandler, {passive: false}); document.addEventListener ('touchmove', touchmoveHandler, {pasif: yanlış});
Anton Kuzmin

4

Saf CSS'de en iyi çözüm:

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

Bu demoya bakın: https://jsbin.com/pokusideha/quiet


Bunu krom kullanan bir mobil cihazda gerçekten test ettiniz mi?
Gregor Voinov


3

Vücudunuzun CSS taşmasını ayarlıyorum -y: gizli en basit yoldur. Kaydırma uygulama sayfanız olmasını istiyorsanız, kaydırma özelliklerine sahip bir div kapsayıcı kullanabilirsiniz.


Bir çizgi ile düzeltmek imkansız görünüyor, ancak bir cazibe gibi çalışıyor, çok teşekkürler!
Ignacio Ara

2

Overflow-y'nin kalıtsal olmadığına dikkat edin, bu yüzden onu TÜM blok öğelerinde ayarlamanız gerekir.

Bunu jQuery ile kolayca yapabilirsiniz:

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

Diğer cevaplar arasında bu gerçekten yardımcı oluyor. Teşekkürler. Bu satırı css'e ekleyin. gövde {taşma-y: gizli; }
Sarin JS

2

Birkaç haftadan beri Chrome yenileme işlemini devre dışı bırakmak için kullandığım javascript işlevinin artık çalışmadığını öğrendim. Bunu çözmek için yaptım:

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

Saf js çözeltisi.

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

Ne yaptım touchstartve touchend/ touchcancelevents aşağıdaki eklemek oldu :

scrollTo(0, 1)

Krom scrollY konumunda değilse kaydırma yapmadığından, kromun 0yenileme için yenileme yapmasını önler.

Hala çalışmıyorsa, sayfa yüklendiğinde de bunu deneyin.


0

Yenilemek için açılan bu sorunu çözdüm:

html, body {
    width: 100%;
    height: 100%;
    overflow: hidden;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.