safari ipad: menonaktifkan scrolling, dan efek bouncing?


126

Saya sedang mengerjakan aplikasi berbasis browser, saat ini saya sedang mengembangkan dan menata untuk browser safari ipad.

Saya mencari dua hal di ipad: Bagaimana cara menonaktifkan pengguliran vertikal untuk halaman yang tidak memerlukannya? & bagaimana cara menonaktifkan efek pantulan elastis?


lihat jawaban berikut hanya satu yang berhasil untuk saya dan saat ini ( stackoverflow.com/a/51176339/1979180 )
frage

Jawaban:


157

Jawaban ini tidak lagi berlaku, kecuali Anda mengembangkan untuk perangkat iOS yang sangat lama ... Silakan lihat solusi lain


Jawaban 2011: Untuk aplikasi web / html yang berjalan di dalam iOS Safari, Anda menginginkan sesuatu seperti

document.ontouchmove = function(event){
    event.preventDefault();
}

Untuk iOS 5 Anda mungkin ingin mempertimbangkan hal-hal berikut: document.ontouchmove dan scrolling di iOS 5

Pembaruan September 2014: Pendekatan yang lebih menyeluruh dapat ditemukan di sini: https://github.com/luster-io/prevent-overscroll . Untuk itu dan banyak lagi saran aplikasi web yang berguna, lihat http://www.luster.io/blog/9-29-14-mobile-web-checklist.html

Pembaruan Maret 2016: Tautan terakhir itu tidak lagi aktif - lihat https://web.archive.org/web/20151103001838/http://www.luster.io/blog/9-29-14-mobile-web-checklist .html untuk versi yang diarsipkan. Terima kasih @falsarella karena telah menunjukkannya.


1
Saya memiliki aplikasi web yang berjalan di dalam iOS Safari dan saya telah mencoba menonaktifkan acara ontouchmove tetapi masih mungkin untuk melihat efek pantulan jika dilakukan dengan hati-hati. (iOS 5)
Nilesh

7
Bagaimana dengan menonaktifkan efek bouncing ...?
Yuval A.

6
Masalah dengan pendekatan ini adalah, div yang dapat digulir di dom Anda tidak akan menggulir lagi. Bergantung pada pengaturan dom Anda, ada beberapa cara untuk melakukannya.
huesforalice

3
Ada banyak orang di sini bertanya tentang menggulir div saat menggunakan ini jadi .. untuk membuat div tersebut dapat digulir, tambahkan onTouchMove: function(e) { e.stopPropagation(); e.stopImmediatePropagation(); } Ini akan mencegah kejadian mengenai tubuh, tetapi badan akan tetap tidak goyang. Edit: Ini dengan asumsi Anda menyetel $ ('div'). On ('touchmove', ... onTouchMove);
Matt Kenefick

1
@OskarAustegard Tautan terakhir tidak berfungsi untuk saya, tetapi saya dapat menemukan konten di arsip web: web.archive.org/web/20151103001838/http://www.luster.io/blog/…
falsarella

116

Anda juga dapat mengubah posisi body / html menjadi tetap:

body,
html {
  position: fixed;
}

2
Ini sebenarnya bekerja sangat baik di iPad iOS 8.2 Safari; tidak ada efek bouncing lagi.
Akseli Palén

3
Cara terbaik untuk melakukan itu yang pernah saya lihat sejauh ini
hildende

8
Tidak berfungsi jika Anda ingin menempatkan sesuatu dengan posisi: absolut dan semua sisi disetel ke 0 (untuk membuat div layar penuh) - seluruh dokumen Anda menyusut menjadi nol.
riv

4
Halaman itu melompat kembali ke atas halaman untuk saya ketika saya menggunakan ini dan kemudian saya fokus pada masukan. Apakah Anda tahu jalan keluarnya?
Julie

1
@riv menambahkan lebar: 100%; tinggi: 100% untuk body dan html membantu saya.
Tim

58

Untuk mencegah pengguliran di browser seluler modern, Anda perlu menambahkan pasif: false. Saya telah menarik rambut saya agar ini berfungsi sampai saya menemukan solusi ini. Saya hanya menemukan ini disebutkan di satu tempat lain di internet.

function preventDefault(e){
    e.preventDefault();
}

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault);
}


7
Tanpa { passive: false }itu pasti tidak berhasil !!! Selamat datang di StackOverflow dude
Ser

2
Saya menghargai Anda karena telah memberikan solusi ini!
Paul Z.

6
Ini jawaban yang benar. Anda dapat melihat penjelasannya di sini: developer.mozilla.org/en-US/docs/Web/API/EventTarget/… setelah Chrome 54 touchmove default pasif menjadi true yang berarti panggilan preventDefault akan diabaikan. Itulah mengapa Anda harus meneruskan {passive: false}, sehingga panggilan preventDefault tidak diabaikan.
derickito

1
Anda mendeklarasikan fungsi di JS - Tapi bagaimana Anda memanggil fungsi ini pada sebuah elemen sehingga berfungsi seperti yang disarankan?
ikwyl6

4
Ini berfungsi dengan baik jika Anda ingin menonaktifkan semua jenis pengguliran. Tetapi bagaimana jika saya hanya ingin menonaktifkan gulir pada tubuh dan menjaga kemungkinan untuk menggulir pada elemen dengan overflow-y: scroll? Misalnya memiliki modal dengan view height lebih tinggi dari body.
Calsal

7

Anda dapat menggunakan cuplikan kode jQuery ini untuk melakukan ini:

$(document).bind(
      'touchmove',
          function(e) {
            e.preventDefault();
          }
);

Ini akan memblokir pengguliran vertikal dan juga efek memantul kembali yang terjadi di halaman Anda.


11
Ini bukan Javascript, ini jQuery. Anda harus menyebutkan bahwa, tidak semua orang menggunakan kerangka itu.
inta

bagaimana saya bisa menghentikan pantulan horizontal atau gulir
fidel castro

Gulir horizontal Anda bahkan dapat menonaktifkannya hanya dengan css, menerapkan overflow-x: hidden; ke wadah utama Anda. Saya perhatikan di versi terbaru safari Anda tidak dapat menonaktifkan efek bouncing sekalipun. Ini adalah fitur asli browser di perangkat seluler.
Alessandro Incarnati

6
@inta Hanya mengatakan ini sebenarnya adalah javascript. Ini bukan javascript murni.
Ben Lorantfy


4

Saya tahu ini sedikit off-piste tetapi saya telah menggunakan Swiffy untuk mengubah Flash menjadi game HTML5 interaktif dan menemukan masalah pengguliran yang sama tetapi tidak menemukan solusi yang berhasil.

Masalah yang saya hadapi adalah bahwa tahapan Swiffy memenuhi seluruh layar, jadi segera setelah dimuat, peristiwa touchmove dokumen tidak pernah dipicu.

Jika saya mencoba menambahkan acara yang sama ke penampung Swiffy, itu diganti segera setelah panggung dimuat.

Pada akhirnya saya menyelesaikannya (agak berantakan) dengan menerapkan event touchmove ke setiap DIV di dalam panggung. Karena div ini juga selalu berubah, saya perlu terus memeriksanya.

Ini adalah solusi saya, yang tampaknya berhasil dengan baik. Saya harap ini membantu orang lain yang mencoba menemukan solusi yang sama dengan saya.

var divInterval = setInterval(updateDivs,50);
function updateDivs(){
$("#swiffycontainer > div").bind(
    'touchmove',
     function(e) {
        e.preventDefault();
    }
);}

ini menonaktifkan seluruh gulungan di ipad
fidel castro

3

Kode untuk Untuk menghapus safari ipad: nonaktifkan scrolling, dan efek bouncing

   document.addEventListener("touchmove", function (e) {
        e.preventDefault();
    }, { passive: false });

Jika Anda memiliki tag canvas di dalam dokumen, terkadang hal itu akan mempengaruhi kegunaan objek di dalam kanvas (contoh: pergerakan objek); jadi tambahkan kode di bawah ini untuk memperbaikinya.

    document.getElementById("canvasId").addEventListener("touchmove", function (e) {
        e.stopPropagation();
    }, { passive: false });

2

Coba sollutuion JS ini :

var xStart, yStart = 0; 

document.addEventListener('touchstart', function(e) {
    xStart = e.touches[0].screenX;
    yStart = e.touches[0].screenY;
}); 

document.addEventListener('touchmove', function(e) {
    var xMovement = Math.abs(e.touches[0].screenX - xStart);
    var yMovement = Math.abs(e.touches[0].screenY - yStart);
    if((yMovement * 3) > xMovement) {
        e.preventDefault();
    }
});

Mencegah gerakan menggulir dan memantul Safari default tanpa melepaskan pendengar acara sentuh Anda.


Ini menghentikan aplikasi web untuk menggulir sepenuhnya pada elemen body.
MartijnICU

2

tidak ada solusi yang berhasil untuk saya. Beginilah cara saya melakukannya.

  html,body {
      position: fixed;
      overflow: hidden;
    }
  .the_element_that_you_want_to_have_scrolling{
      -webkit-overflow-scrolling: touch;
  }

Saya akan melakukan .the_element_that_you_want_to_have_scrolling {scrolling: touch; }
Roy Segall

Jawaban Anda berhasil untuk saya untuk html, body tetapi saya tidak bisa mendapatkan "the_element_that_you_want_to_have_scrolling" untuk menggulir. Elemen ini bertumpuk di dalam beberapa div yang berada di bawah badan. Apakah penting apa pun dari tag elemen tipikal untuk div bersarang ini yang saya ingin gulirkan? Saya memiliki posisi: relatif.
ikwyl6


1

Bagi mereka yang menggunakan MyScript, Aplikasi Web dan berjuang dengan menggulir / menyeret tubuh (di iPad dan Tablet) alih-alih benar-benar menulis:

<body touch-action="none" unresolved>

Itu memperbaikinya untuk saya.


1

Anda dapat menggunakan js untuk mencegah gulir:

let body = document.body;

let hideScroll = function(e) {
  e.preventDefault();
};

function toggleScroll (bool) {

  if (bool === true) {
    body.addEventListener("touchmove", hideScroll);
  } else {
    body.removeEventListener("touchmove", hideScroll);
  }
}

Dan dari sekedar lari / berhenti toggleScroll fungsi saat Anda membuka / menutup modal.

Seperti ini toggleScroll(true) / toggleScroll(false)

(Ini hanya untuk iOS, di Android tidak berfungsi)


1

Coba solusi JS ini yang mengubah webkitOverflowScrollinggaya. Triknya di sini adalah bahwa gaya ini tidak aktif, Safari seluler beralih ke pengguliran biasa dan mencegah pantulan berlebih - sayangnya, ini tidak dapat membatalkan seret yang sedang berlangsung. Solusi kompleks ini juga melacak onscrollsebagai pantulan di atas membuat scrollTopnegatif yang dapat dilacak. Solusi ini telah diuji pada iOS 12.1.1 dan memiliki satu kelemahan: sementara mempercepat gulir, pantulan tunggal masih terjadi karena menyetel ulang gaya mungkin tidak langsung membatalkannya.

function preventScrollVerticalBounceEffect(container) {
  setTouchScroll(true) //!: enable before the first scroll attempt

  container.addEventListener("touchstart", onTouchStart)
  container.addEventListener("touchmove", onTouch, { passive: false })
  container.addEventListener("touchend", onTouchEnd)
  container.addEventListener("scroll", onScroll)

  function isTouchScroll() {
    return !!container.style.webkitOverflowScrolling
  }

  let prevScrollTop = 0, prevTouchY, opid = 0

  function setTouchScroll(on) {
    container.style.webkitOverflowScrolling = on ? "touch" : null

    //Hint: auto-enabling after a small pause makes the start
    // smoothly accelerated as required. After the pause the
    // scroll position is settled, and there is no delta to
    // make over-bounce by dragging the finger. But still,
    // accelerated content makes short single over-bounce
    // as acceleration may not be off instantly.

    const xopid = ++opid
    !on && setTimeout(() => (xopid === opid) && setTouchScroll(true), 250)

    if(!on && container.scrollTop < 16)
      container.scrollTop = 0
    prevScrollTop = container.scrollTop
  }

  function isBounceOverTop() {
    const dY = container.scrollTop - prevScrollTop
    return dY < 0 && container.scrollTop < 16
  }

  function isBounceOverBottom(touchY) {
    const dY = touchY - prevTouchY

    //Hint: trying to bounce over the bottom, the finger moves
    // up the screen, thus Y becomes smaller. We prevent this.

    return dY < 0 && container.scrollHeight - 16 <=
      container.scrollTop + container.offsetHeight
  }

  function onTouchStart(e) {
    prevTouchY = e.touches[0].pageY
  }

  function onTouch(e) {
    const touchY = e.touches[0].pageY

    if(isBounceOverBottom(touchY)) {
      if(isTouchScroll())
        setTouchScroll(false)
      e.preventDefault()
    }

    prevTouchY = touchY
  }

  function onTouchEnd() {
    prevTouchY = undefined
  }

  function onScroll() {
    if(isTouchScroll() && isBounceOverTop()) {
      setTouchScroll(false)
    }
  }
}

1

jawaban yang ditingkatkan @Ben Bos dan dikomentari oleh @Tim

Css ini akan membantu mencegah masalah scrolling dan kinerja dengan render ulang css karena posisi berubah / sedikit tertinggal tanpa lebar dan tinggi

body,
html {
  position: fixed;
  width: 100%; 
  height: 100%
}


Di IOS13, ini adalah solusi terbersih bagi saya, dan belum menemukan kekurangan ...
Soylent Graham

0

Bagi Anda yang tidak ingin menyingkirkan pantulan tetapi hanya ingin mengetahui kapan pantulannya berhenti (misalnya untuk memulai beberapa penghitungan jarak layar), Anda dapat melakukan hal berikut (penampung adalah elemen penampung yang meluap):

    const isBouncing = this.container.scrollTop < 0 ||
    this.container.scrollTop + this.container.offsetHeight >
        this.container.scrollHeight

0

Nonaktifkan efek gulir pantulan safari:

html,
body {
  height: 100%;
  width: 100%;
  overflow: auto;
  position: fixed;
}  

-1

Mirip dengan kiwi yang marah, saya membuatnya bekerja menggunakan ketinggian daripada posisi:

html,body {
  height: 100%;
  overflow: hidden;
}

.the_element_that_you_want_to_have_scrolling{
  -webkit-overflow-scrolling: touch;
}

sebagai dokumen ini akan mengaktifkan pantulan juga setelah momentum tidak menonaktifkan
CaSUaL

@CaSUaL Tidak yakin apa yang Anda maksud? Solusi ini bekerja untuk kasus penggunaan saya ...
austinh7

-1

Solusi diuji, berfungsi pada iOS 12.x

Inilah masalah yang saya hadapi:

<body> <!-- the whole body can be scroll vertically -->
  <article>

    <my_gallery> <!-- some picture gallery, can be scroll horizontally -->
    </my_gallery>

  </article>
</body>

Saat saya menggulir galeri saya, tubuh selalu menggulir sendiri (gesekan manusia tidak terlalu horizontal), yang membuat galeri saya tidak berguna.

Inilah yang saya lakukan saat galeri saya mulai bergulir

var html=jQuery('html');
html.css('overflow-y', 'hidden');
//above code works on mobile Chrome/Edge/Firefox
document.ontouchmove=function(e){e.preventDefault();} //Add this only for mobile Safari

Dan ketika galeri saya mengakhiri penggulirannya ...

var html=jQuery('html');
html.css('overflow-y', 'scroll');
document.ontouchmove=function(e){return true;}

Semoga ini bisa membantu ~

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.