Menonaktifkan fitur pull-down-to-refresh chrome android

137

Saya telah membuat aplikasi web HTML5 kecil untuk perusahaan saya.

Aplikasi ini menampilkan daftar item dan semuanya berfungsi dengan baik.

Aplikasi ini terutama digunakan pada ponsel android dan Chrome sebagai browser. Selain itu, situs tersebut disimpan di layar beranda sehingga Android mengelola semuanya sebagai aplikasi ( saya kira menggunakan WebView ).

Chrome Beta (dan menurut saya juga Android System WebView) telah memperkenalkan fitur "pull down to refresh" ( Lihat tautan ini misalnya ).

Ini adalah fitur yang berguna tetapi saya bertanya-tanya apakah itu dapat dinonaktifkan dengan beberapa meta tag (atau barang javascript) karena penyegaran dapat dengan mudah dipicu oleh pengguna saat menavigasi daftar dan seluruh aplikasi dimuat ulang.

Juga ini adalah fitur yang tidak dibutuhkan oleh aplikasi.

Saya tahu bahwa fitur ini masih tersedia hanya di Chrome beta, tetapi saya merasa fitur ini juga tersedia di aplikasi stabil.

Terima kasih!

Sunting: Saya telah mencopot pemasangan Chrome Beta dan tautan yang disematkan ke layar beranda sekarang terbuka dengan Chrome yang stabil. Jadi tautan yang disematkan dimulai dengan Chrome dan bukan dengan tampilan web.

Sunting: hari ini (2015-03-19) pull-down-to-refresh telah datang ke chrome stabil.

Sunting: dari jawaban @Evyn Saya mengikuti tautan ini dan mendapatkan kode javascript / jquery yang berfungsi.

Seperti yang ditunjukkan oleh @bcintegrity, saya berharap solusi nyata situs (dan / atau meta-tag) di masa mendatang.

Selain itu saran untuk kode di atas dipersilakan.

Sebastiano
sumber
19
Ya, ini sangat menyebalkan. Berada di tengah bentuk dan digulir ke atas terlalu jauh dan itu menyegarkan dan kehilangan segalanya. Ini adalah fitur default terbelakang, saya mengklik ikon Refresh jika saya ingin menyegarkan!
Brock Hensley
12
Alangkah baiknya jika fitur ini dapat dinonaktifkan di manifes aplikasi web saya. Sayangnya, setiap halaman di aplikasi web saya memiliki konten yang dapat digulir, sehingga hampir tidak mungkin untuk dinavigasi tanpa penyegaran. Saya sedikit berdetak. : /
bcintegrity
Ini info yang bagus. Saya benci situs web yang menonaktifkan fitur tarik untuk menyegarkan. Saya ingin mengembangkan fitur agar penyegaran berfungsi terlepas dari konten halaman.
Tn. Lance E Sloan
5
Berbicara sebagai pengembang web, penyegaran pulldown tidak kompatibel dengan situs web berbasis data, karena memuat ulang aplikasi. Itu membuat pengguna tidak mungkin untuk menggulir ke bagian atas halaman tanpa menyegarkan seluruh halaman. Saya 100% mendukung Chrome, semoga mereka menghapus fitur anti ini.
Kacang
3
Saya menghadapi diri saya sendiri dengan "fitur" GC ini ... banyak halaman web, banyak bentuk, satu tarikan yang ceroboh dengan jari saya dan data di halaman ini hilang! Perlambat fungsi IMO. Ini harus dimatikan secara default, yang membutuhkannya kemudian biarkan kode itu. Saya bertanya-tanya mengapa "klien" saya terkadang kehilangan data mereka di GC ...
Ludus H

Jawaban:

160

Tindakan default dari efek tarik-untuk-menyegarkan dapat dicegah secara efektif dengan melakukan salah satu hal berikut:

  1. preventDefaultbeberapa bagian dari urutan sentuhan, termasuk salah satu dari berikut ini (dalam urutan dari yang paling mengganggu hingga paling tidak mengganggu):
    • Sebuah. Seluruh aliran sentuh (tidak ideal).
    • b. Semua gerakan sentuh overscrolling teratas.
    • c. Gerakan sentuh overscrolling teratas pertama.
    • d. Gerakan sentuh overscrolling pertama hanya ketika 1) touchstart awal terjadi ketika offset gulir halaman y nol dan 2) gerakan sentuh akan menyebabkan overscroll atas.
  2. Menerapkan "touch-action: none " ke elemen target sentuh, jika sesuai, menonaktifkan tindakan default (termasuk tarik untuk menyegarkan) dari urutan sentuh.
  3. Menerapkan "overflow-y: hidden " ke elemen tubuh, menggunakan div untuk konten yang dapat digulir jika perlu.
  4. Menonaktifkan efek secara lokal melalui chrome://flags/#disable-pull-to-refresh-effect).

Lihat lebih banyak

Evyn
sumber
12
Terima kasih @Evyn. Saya tidak percaya ini adalah perbaikan cepat! Saya mengatur CSS untuk elemen body ke overflow-y: hidden.
bcintegrity
Terima kasih @Evyn, saya telah memutuskan untuk menggunakan metode preventDefault () (poin pertama). Secara khusus saya menemukan menarik kode sumber dari tautan ( tautan ) yang ada di dalam dokumen yang telah Anda tautkan . Saya akan meletakkan kode di akhir pertanyaan saya.
Sebastiano
2
bagaimana "chrome: // flags (disable-pull-to-refresh-effect)" dilakukan secara terprogram?
Seseorang Di Suatu Tempat
2
@SomeoneSomewhere sejauh yang saya tahu, itu bukan tidak mungkin. setelan chrome hanya dapat disetel oleh pengguna - jika tidak, ini akan menimbulkan risiko keamanan
Mike
1
Menerapkan "overflow-y: hidden" ke elemen body, menggunakan div untuk konten yang dapat digulir berhasil untuk saya.
Robin
109

Solusi sederhana untuk 2019+

Chrome 63 telah menambahkan properti css untuk membantu hal ini. Bacalah panduan dari Google ini untuk mendapatkan ide bagus tentang bagaimana Anda dapat menanganinya.

Ini TL mereka: DR

Properti CSS overscroll-behaviour memungkinkan pengembang untuk mengganti perilaku scroll overflow default browser saat mencapai bagian atas / bawah konten. Kasus penggunaan termasuk menonaktifkan fitur tarik-untuk-menyegarkan di ponsel, menghapus cahaya gulir berlebihan dan efek gosok, dan mencegah konten laman menggulir saat berada di bawah modal / hamparan.

Untuk membuatnya berfungsi, yang harus Anda tambahkan adalah ini di CSS Anda:

body {
  overscroll-behavior: contain;
}

Ini juga hanya didukung oleh Chrome, Edge dan Firefox untuk saat ini tetapi saya yakin Safari akan menambahkannya segera setelah mereka tampaknya sepenuhnya terintegrasi dengan pekerja layanan dan masa depan PWA.

Matthew Mullin
sumber
17
ini adalah jawaban terbaru
colxi
Apakah ada orang lain yang memperhatikan bahwa ini menunda kemunculan spanduk chrome "Tambahkan ke Layar Beranda"?
Bukit Nathaniel
3
harus menerapkannya ke elemen html untuk menonaktifkannya
Jakob Eriksson
1
Ini hanya berfungsi untuk Android, Chrome di IO masih menunjukkan efek bersinar + tarikan asli untuk menyegarkan
Fky
developers.google.com/web/updates/2017/11/overscroll-behavior tautan ini juga dapat menjelaskan dengan lebih baik
arung86
15

Saat ini Anda hanya dapat menonaktifkan fitur ini melalui chrome: // flags / # disable-pull-to-refresh-effect - buka langsung dari perangkat Anda.

Anda dapat mencoba mengejar ketinggalan touchmove, tetapi kemungkinannya sangat kecil untuk mencapai hasil yang dapat diterima.

Kevin Sandow
sumber
1
Terima kasih Kevin atas jawabannya. Saya tidak dapat menerima ini sebagai yang diterima karena saya mencari sesuatu yang tidak tergantung dari pengguna. Namun metode ini berhasil, jadi saya akan mendukung jawaban Anda karena saya mendapatkan reputasi yang cukup.
Sebastiano
Sayang sekali ini tampaknya menjadi solusi terbaik - bagaimana jika pengaturan bendera berubah di masa mendatang, atau Anda ingin dapat menggunakan tarik untuk menyegarkan di situs lain ... Terkejut bahwa ini tidak dapat dikontrol secara terprogram. :(.
user1063287
1
Jika CEO Google membaca ini, hapus fitur ini. Tampaknya tidak dapat dengan mudah dan lengkap dinonaktifkan, dan menurut saya merupakan "fitur" aplikasi web yang tidak semua aplikasi web inginkan.
pengguna1063287
8

Saya menggunakan MooTools, dan saya telah membuat Kelas untuk menonaktifkan penyegaran pada elemen yang ditargetkan, tetapi intinya adalah (JS asli):

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

Yang kita lakukan di sini adalah mencari arah y dari gerakan sentuh, dan jika kita bergerak ke bawah layar dan target scroll adalah 0, kita menghentikan kejadian tersebut. Jadi, tidak ada penyegaran.

Ini berarti kami melakukan setiap 'gerakan', yang bisa jadi mahal, tetapi merupakan solusi terbaik yang saya temukan sejauh ini ...

Eklektik
sumber
2
Aman untuk berhenti menonton segera setelah pengguna menggulir ke bawah, karena tarikan untuk menyegarkan tidak memiliki peluang untuk dipicu. Begitu juga jika scrolltop > 0, acara tidak akan dipicu. Dalam implementasinya, saya mengikat touchmoveacara tersebut touchstart, hanya jika scrollTop <= 0. Saya melepaskannya segera setelah pengguna menggulir ke bawah ( initialY >= e.touches[0].clientY). Jika pengguna menggulir ke atas ( previousY < e.touches[0].clientY), maka saya memanggil preventDefault.
Nicolas Bouliane
8

Setelah berjam-jam mencoba, solusi ini berhasil untuk saya

$("html").css({
    "touch-action": "pan-down"
});
José Loguercio
sumber
Tidak perlu menggunakan jQuery untuk ini. Cukup tambahkan "touch-action: pan-down" ke file kode css Anda.
Keegan Teetaert
1
cukup gunakan ini di css Anda:html{touch-action:pan-down}
csandreas1
5

AngularJS

Saya telah berhasil menonaktifkannya dengan direktif AngularJS ini:

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

Aman untuk berhenti menonton segera setelah pengguna menggulir ke bawah, karena tarikan untuk menyegarkan tidak mungkin dipicu.

Begitu juga jika scrolltop > 0, acara tidak akan dipicu. Dalam implementasinya, saya mengikat event touchmove pada touchstart, hanya jika scrollTop <= 0. Saya melepaskannya segera setelah pengguna menggulir ke bawah ( initialY >= e.touches[0].clientY). Jika pengguna menggulir ke atas ( previousY < e.touches[0].clientY), maka saya memanggilpreventDefault() .

Ini menyelamatkan kita dari menonton acara gulir yang tidak perlu, namun memblokir overscrolling.

jQuery

Jika Anda menggunakan jQuery, ini adalah padanan yang belum teruji . elementadalah elemen 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);

Secara alami, hal yang sama juga bisa dicapai dengan JS murni.

Nicolas Bouliane
sumber
Saya harus menggunakan e.originalEvent.touches[0].clientYuntuk membuat ini bekerja. Masih berkutat dengan logika saat mencegah reload. Saat ini tampaknya mencegah pengguliran secara acak ... Terima kasih atas petunjuk ke arah yang benar!
Thomas
Elemen apa yang direktif ditambahkan?
Fizzix
Arahan AngularJS bekerja dengan baik untuk saya. Kami menggunakan Framework7 dan Angular bersama-sama (tidak menyarankannya) dan ada sesuatu yang memblokir perilaku scrollTop yang benar. Jadi saya harus memodifikasi kapan blockScroll akan ditambahkan ke elemen. Tapi hanya ingin mengucapkan terima kasih!
Dustin Jensen
5

Javascript sederhana

Saya menerapkan menggunakan javascript standar. Sederhana dan mudah diterapkan. Cukup tempel dan berfungsi dengan baik.

<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>
Sacky San
sumber
Ini bekerja sangat baik untuk Chrome, tetapi menyebabkan beberapa masalah dengan menggulir ke atas untuk saya di Safari / iOS 9.2 saat menggulir div di bagian atas halaman (direproduksi di sini ). Saya akhirnya menggunakan body: {overflow-y:hidden}trik dari Evyn di atas .
sennett
downvoting tidak berfungsi di chrome, tetapi berfungsi di contoh firefox, embed.plnkr.co/rqbOVSOkKyhAgoHK2sEP buka HANYA di SELULER
vijay
tautan yang Anda tempel juga berfungsi di chrome di ponsel Android saya. itu tidak memungkinkan untuk menyegarkan saat ditarik. versi android / ios mana yang Anda gunakan untuk menguji?
Sacky San
2
Dari Chrome 56 Anda perlu menyetel pasif: false agar berfungsi: document.addEventListener ('touchstart', touchstartHandler, {passive: false}); document.addEventListener ('touchmove', touchmoveHandler, {pasif: false});
Anton Kuzmin
4

Solusi terbaik untuk CSS murni:

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

Lihat demo ini: https://jsbin.com/pokusideha/quiet

Eugene Fox
sumber
apakah Anda benar-benar menguji ini di ponsel menggunakan chrome?
Gregor Voinov
3

Saya menemukan pengaturan CSS tubuh Anda overflow-y: hidden adalah cara termudah. Jika Anda memang ingin memiliki halaman aplikasi scrolling, Anda bisa menggunakan wadah div dengan fitur scrolling.

Keegan Teetaert
sumber
Sepertinya tidak mungkin untuk memperbaikinya dengan garis tetapi berfungsi seperti pesona, terima kasih banyak!
Ignacio Ara
2

Perhatikan bahwa overflow-y tidak diwariskan, jadi Anda perlu menyetelnya di SEMUA elemen blok.

Anda dapat melakukan ini dengan jQuery hanya dengan:

        $(document.body).css('overflow-y', 'hidden'); 
        $('*').filter(function(index) {
            return $(this).css('display') == 'block';
        }).css('overflow-y', 'hidden');
kofifus.dll
sumber
Di antara jawaban lainnya, yang ini sangat membantu. Terima kasih. Tambahkan baris ini ke dalam css. body {overflow-y: hidden; }
Sarin JS
2

Sejak beberapa minggu saya menemukan bahwa fungsi javascript yang saya gunakan untuk menonaktifkan tindakan penyegaran Chrome tidak akan berfungsi lagi. Saya telah membuat ini untuk menyelesaikannya:

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

Wobbo
sumber
1

Solusi js murni.

// 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);
pengguna1503606
sumber
0

Apa yang saya lakukan adalah menambahkan yang berikut ke touchstartdan touchend/ touchcancelperistiwa:

scrollTo(0, 1)

Karena chrome tidak menggulir jika tidak dalam posisi scrollY, 0ini akan mencegah chrome melakukan tarik untuk menyegarkan.

Jika masih tidak berhasil, coba lakukan juga saat halaman dimuat.

xdevs23
sumber
0

Saya memecahkan masalah pull-down-to-refresh dengan ini:

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