ipad safari: kaydırma ve zıplama efekti devre dışı bırakılsın mı?


126

Tarayıcı tabanlı bir uygulama üzerinde çalışıyorum, şu anda ipad safari tarayıcısı için geliştiriyorum ve şekillendiriyorum.

İpad'de iki şey arıyorum: Gerekmeyen sayfalar için dikey kaydırmayı nasıl devre dışı bırakabilirim? & elastik sıçrama etkisini nasıl devre dışı bırakabilirim?


aşağıdaki yanıta bakın yalnızca benim için işe
yarayan

Yanıtlar:


157

Çok eski bir iOS cihazı için geliştirme yapmıyorsanız, bu cevap artık geçerli değildir ... Lütfen diğer çözümlere bakın


2011 yanıtı: iOS Safari'de çalışan bir web / html uygulaması için şuna benzer bir şey istiyorsunuz:

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

İOS 5 için şunları hesaba katmak isteyebilirsiniz: document.ontouchmove ve iOS 5'te kaydırma

Eylül 2014 Güncellemesi: Daha kapsamlı bir yaklaşım burada bulunabilir: https://github.com/luster-io/prevent-overscroll . Bunun ve pek çok yararlı web uygulaması tavsiyesi için bkz. Http://www.luster.io/blog/9-29-14-mobile-web-checklist.html

Güncelleme Mart 2016: Bu son bağlantı artık aktif değil - bkz https://web.archive.org/web/20151103001838/http://www.luster.io/blog/9-29-14-mobile-web-checklist bunun yerine arşivlenmiş sürüm için .html . Bunu belirttiğiniz için @falsarella'ya teşekkürler.


1
İOS Safari'de çalışan web uygulamam var ve ontouchmove olayını devre dışı bırakmayı denedim, ancak dikkatlice yapılırsa yine de sıçrama etkisini görmek mümkün. (iOS 5)
Nilesh

7
Geri dönme efektini devre dışı bırakmaya ne dersiniz?
Yuval A.

6
Bu yaklaşımla ilgili sorun, alanınızdaki kaydırılabilir div'lerin artık kaydırılmamasıdır. Dom kurulumunuza bağlı olarak, bunun etrafında yollar vardır.
huesforalice

3
Burada, bunu kullanırken div'leri kaydırmayı soran bir grup insan var, bu yüzden .. bu div'leri kaydırılabilir hale getirmek için, ekleyin onTouchMove: function(e) { e.stopPropagation(); e.stopImmediatePropagation(); } Bu, olayın vücuda çarpmasını önleyecek, ancak vücut zıplamadan kalacaktır. Düzenleme: Bu, $ ['div']. On ('touchmove', ... onTouchMove);
Matt Kenefick

1
@OskarAustegard Son bağlantı benim için çalışmadı, ancak içeriği web arşivinde bulabildim
falsarella

116

Ayrıca body / html'nin konumunu sabit olarak değiştirebilirsiniz:

body,
html {
  position: fixed;
}

2
Bu aslında iPad iOS 8.2 Safari'de çok iyi çalıştı; artık sıçrama etkisi yok.
Akseli Palén

3
Bunu yapmanın şimdiye kadar gördüğüm en iyi yolu
hildende

8
Konum olan bir şey yerleştirmek istiyorsanız işe yaramaz: mutlak ve tüm taraflar 0'a ayarlanmış (tam ekran bir div yapmak için) - tüm belgeniz küçülür.
riv

4
Bunu kullandığımda sayfa benim için sayfanın üstüne geri dönüyor ve sonra bir girdiye odaklanıyorum. Bunun bir yolunu biliyor musun?
Julie

1
@riv genişlik ekleyerek:% 100; height: body ve html% 100 bana yardımcı oldu.
Tim

58

Modern mobil tarayıcılarda kaydırmayı önlemek için passive: false eklemeniz gerekir. Bu çözümü bulana kadar bunu işe yarayabilmek için saçımı çekiyordum. Bu sözü internette başka bir yerde buldum.

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

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


7
Olmadan { passive: false }kesinlikle çalışmıyor !!! StackOverflow'a hoş geldiniz dude
Ser

2
Bu çözümü sağladığınız için teşekkür ederim!
Paul Z.

6
Bu doğru cevap. Açıklamayı burada görebilirsiniz: developer.mozilla.org/en-US/docs/Web/API/EventTarget/… Chrome 54 touchmove varsayılan pasif olarak true olarak ayarlandıktan sonra, bu, preventDefault çağrılarının yok sayılacağı anlamına gelir. Bu yüzden {passive: false} 'i geçmelisiniz, böylece preventDefault çağrısı göz ardı edilmez.
derickito

1
İşlevi JS'de bildiriyorsunuz - Ama bu işlevi bir öğede nasıl çağırırsınız, böylece önerilen şekilde çalışır?
ikwyl6

4
Her türlü kaydırmayı devre dışı bırakmak istiyorsanız bu harika çalışıyor. Peki ya yalnızca gövde üzerindeki kaydırmayı devre dışı bırakmak ve ile bir öğede kaydırma olasılığını korumak istersem overflow-y: scroll? Örneğin, görünüm yüksekliği vücuttan daha uzun olan bir modele sahip olmak.
Calsal

7

Bunu yapmak için bu jQuery kod parçacığını kullanabilirsiniz:

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

Bu, dikey kaydırmayı ve ayrıca sayfalarınızda meydana gelen herhangi bir geri dönme etkisini engelleyecektir.


11
Bu Javascript değil, jQuery. Bundan bahsetmelisiniz, herkes bu çerçeveyi kullanmıyor.
inta

yatay sıçramayı veya kaydırmayı nasıl durdurabilirim
fidel castro

Yatay kaydırmayı sadece css ile devre dışı bırakabilirsiniz, overflow-x: hidden; ana konteynerinize. Safari'nin son sürümlerinde, sıçrama etkisini devre dışı bırakamayacağınızı fark ettim. Tarayıcının mobil cihazlardaki yerel bir özelliğidir.
Alessandro Incarnati

6
@inta Bunun aslında javascript olduğunu söylüyorum. Sadece saf javascript değil.
Ben Lorantfy


4

Bunun biraz pist dışı olduğunu biliyorum, ancak Flash'ı etkileşimli bir HTML5 oyununa dönüştürmek için Swiffy'yi kullanıyorum ve aynı kaydırma sorunuyla karşılaştım ancak işe yarayan hiçbir çözüm bulamadım.

Karşılaştığım sorun, Swiffy sahnesinin tüm ekranı kaplamasıydı, bu nedenle yüklenir yüklenmez, belge dokunma hareketi hiçbir zaman tetiklenmedi.

Aynı olayı Swiffy konteynırına eklemeye çalışırsam, sahne yüklenir yüklenmez değiştirildi.

Sonunda, touchmove olayını sahne içindeki her DIV'ye uygulayarak (oldukça karışık bir şekilde) çözdüm. Bu div'ler de sürekli değiştiği için onları kontrol etmeye devam etmem gerekiyordu.

Bu benim çözümümdü ve iyi çalışıyor gibi görünüyor. Umarım benimle aynı çözümü bulmaya çalışan herkes için yararlıdır.

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

bu, ipad'de tüm kaydırmayı devre dışı bırakır
fidel castro

3

İpad safari'yi kaldırmak için kodlama: kaydırma ve zıplama efektini devre dışı bırakın

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

Belgenin içinde tuval etiketiniz varsa , bazen bu nesnenin Canvas içindeki kullanılabilirliğini etkiler (örnek: nesnenin hareketi); bu yüzden düzeltmek için aşağıdaki kodu ekleyin.

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

2

Bu JS çözümünü deneyin :

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

Dokunma etkinliği dinleyicilerinizi ayırmadan varsayılan Safari kaydırma ve sıçrama hareketlerini engeller.


Bu, web uygulamasının gövde öğesinde tamamen kaymasını durdurur.
MartijnICU

2

çözümlerin hiçbiri benim için işe yaramıyor. Ben böyle yaparım.

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

.The_element_that_you_want_to_have_scrolling {scrolling: touch; }
Roy Segall

Cevabınız html, body için benim için çalıştı, ancak kaydırmak için "the_element_that_you_want_to_have_scrolling" i alamıyorum. Bu öğe, gövdenin altındaki birkaç div'in içine yerleştirilmiştir. Kaydırmasını istediğim bu iç içe geçmiş div için tipik öğe etiketlerinin ne olduğu önemli mi? Konumum var: akraba.
ikwyl6


1

MyScript the Web App kullanan ve aslında yazmak yerine gövde kaydırma / sürükleme (iPad ve Tabletlerde) ile uğraşanlar için:

<body touch-action="none" unresolved>

Bu benim için sorunumu çözdü.


1

Kaydırmayı önlemek için js kullanabilirsiniz:

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

Ve toggleScrollmodal'ı açtığınızda / kapattığınızda sadece çalıştır / durdur işlevi yerine.

Bunun gibi toggleScroll(true) / toggleScroll(false)

(Bu sadece iOS içindir, Android'de çalışmıyor)


1

webkitOverflowScrollingStili değiştiren bu JS çözümünü deneyin . Buradaki hile, bu tarzın kapalı olması, mobil Safari'nin normal kaydırmaya gitmesi ve aşırı sıçramayı engellemesidir - ne yazık ki, devam eden sürüklemeyi iptal edemez. Bu karmaşık çözüm aynı zamanda onscroll, üstteki sıçrama scrollTopizlenebilecek negatif hale getirirken izler . Bu çözüm, iOS 12.1.1'de test edilmiştir ve tek bir dezavantajı vardır: Kaydırma hızlandırılırken, stilin sıfırlanması onu hemen iptal edemeyebileceğinden, tek aşırı sıçrama yine de gerçekleşir.

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

geliştirilmiş cevap @ Ben Bos ve @ Tim tarafından yorumlandı

Bu css, konum değiştiğinden / genişlik ve yükseklik olmadan çok az gecikme olduğundan, css yeniden oluşturma ile kaydırma ve performans sorunlarının önlenmesine yardımcı olur

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


IOS13'te bu benim için en temiz çözüm ve henüz herhangi bir dezavantaj bulamadım ...
Soylent Graham

0

Zıplamadan kurtulmak istemeyen, ancak ne zaman durduğunu bilmek isteyenler için (örneğin, ekran mesafelerinin bazı hesaplamalarına başlamak için), aşağıdakileri yapabilirsiniz (konteyner, taşan konteyner öğesidir):

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

0

Safari sıçrama kaydırma efektini devre dışı bırakın:

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

-1

Kızgın kivi'ye benzer şekilde, pozisyondan ziyade yüksekliği kullanarak çalışmasını sağladım:

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

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

belge olarak bu, momentum devre dışı
bırakılmadıktan

@CaSUaL Ne demek istediğinizden emin değil misiniz? Bu çözüm benim kullanım
durumum

-1

Çözüm test edildi, iOS 12.x üzerinde çalışıyor

Bu karşılaştığım sorun:

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

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

  </article>
</body>

Galerimi kaydırırken, vücut her zaman kendi kendini kaydırıyor (insan kaydırması gerçekten yatay değil), bu da galerimi işe yaramaz hale getiriyor.

Galerim kaymaya başlarken yaptığım şey şöyle

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

Ve galerim kaydırmayı bitirdiğinde ...

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

Umarım bu yardımcı olur ~

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.