Mam aplikację internetową działającą w iOS Safari i próbowałem wyłączyć zdarzenie ontouchmove, ale nadal można zobaczyć efekt odbicia, jeśli zostanie to zrobione ostrożnie. (iOS 5)
Problem z tym podejściem polega na tym, że przewijalne elementy div w Twoim domenie nie będą już przewijać. W zależności od konfiguracji domeny można to obejść.
Jest tu grupa ludzi, którzy pytają o przewijanie elementów div podczas korzystania z tego, więc ... aby umożliwić przewijanie tych elementów div, dodaj. onTouchMove: function(e) { e.stopPropagation(); e.stopImmediatePropagation(); } Zapobiegnie to uderzaniu zdarzenia w ciało, ale treść nie będzie odbijana. Edycja: Zakładamy, że ustawiłeś $ ('div'). On ('touchmove', ... onTouchMove);
Nie działa, jeśli chcesz umieścić coś z pozycją: bezwzględną i wszystkimi bokami ustawionymi na 0 (aby utworzyć pełnoekranowy element div) - cały dokument kurczy się do zera.
Aby zapobiec przewijaniu w nowoczesnych przeglądarkach mobilnych, musisz dodać pasywne: false. Wyrywałem sobie włosy, żeby to zadziałało, dopóki nie znalazłem tego rozwiązania. Znalazłem to wspomniane tylko w jednym miejscu w Internecie.
function preventDefault(e){
e.preventDefault();}function disableScroll(){
document.body.addEventListener('touchmove', preventDefault,{ passive:false});}function enableScroll(){
document.body.removeEventListener('touchmove', preventDefault);}
To jest poprawna odpowiedź. Możesz zobaczyć wyjaśnienie tutaj: developer.mozilla.org/en-US/docs/Web/API/EventTarget/ ... po tym, jak touchmove Chrome 54 domyślnie ustawił wartość pasywną na true, co oznacza, że wywołania disableDefault byłyby ignorowane. Dlatego musisz przekazać {passive: false}, aby wywołanie prevDefault nie było ignorowane.
Działa to świetnie, jeśli chcesz wyłączyć wszystkie rodzaje przewijania. Ale co, jeśli chcę tylko wyłączyć przewijanie treści i zachować możliwość przewijania elementu overflow-y: scroll? Na przykład mając modal z wyższą wysokością widoku niż ciało.
Przewijanie poziome można nawet wyłączyć za pomocą samego css, stosując overflow-x: hidden; do głównego pojemnika. Zauważyłem, że w najnowszych wersjach Safari nie można jednak wyłączyć efektu odbicia. To natywna funkcja przeglądarki na urządzeniach mobilnych.
Razem z overflow:hiddenon the <body>nadal jest to najlepsze rozwiązanie. Jednak podczas otwierania klawiatury lub przesuwania w dół ekranu, nie będzie już działać.
Wiem, że jest to trochę poza trasą, ale używałem Swiffy do konwersji Flasha na interaktywną grę HTML5 i napotkałem ten sam problem z przewijaniem, ale nie znalazłem rozwiązania, które działało.
Problem, jaki miałem, polegał na tym, że scena Swiffy zajmowała cały ekran, więc po załadowaniu zdarzenie dotknięcia dokumentu nigdy nie zostało wyzwolone.
Jeśli próbowałem dodać to samo zdarzenie do kontenera Swiffy, zostało ono zastąpione zaraz po załadowaniu sceny.
W końcu rozwiązałem to (raczej niechlujnie), stosując zdarzenie touchmove do każdego DIV na scenie. Ponieważ te elementy div również się zmieniały, musiałem je sprawdzać.
To było moje rozwiązanie, które wydaje się działać dobrze. Mam nadzieję, że będzie to pomocne dla każdego, kto próbuje znaleźć to samo rozwiązanie co ja.
var divInterval = setInterval(updateDivs,50);
function updateDivs(){
$("#swiffycontainer > div").bind(
'touchmove',
function(e) {
e.preventDefault();
}
);}
Kod do usuwania ipad safari: wyłącz przewijanie i efekt odbijania
document.addEventListener("touchmove", function (e) {
e.preventDefault();
}, { passive: false });
Jeśli masz tag canvas w dokumencie, czasami będzie to miało wpływ na użyteczność obiektu wewnątrz Canvas (przykład: ruch obiektu); więc dodaj poniższy kod, aby to naprawić.
document.getElementById("canvasId").addEventListener("touchmove", function (e) {
e.stopPropagation();
}, { passive: false });
Twoja odpowiedź zadziałała dla mnie w przypadku treści HTML, ale nie mogę przewinąć „the_element_that_you_want_to_have_scrolling”. Ten element jest zagnieżdżony w kilku elementach div znajdujących się pod treścią. Czy ma znaczenie, jakie byłyby typowe znaczniki elementu dla tego zagnieżdżonego elementu div, że chcę, aby był przewijany? Mam pozycję: względną.
Przetestowano na iPhonie. Po prostu użyj tego css na kontenerze elementu docelowego, a zmieni to zachowanie przewijania, które zatrzymuje się, gdy palec opuszcza ekran.
Wypróbuj to rozwiązanie JS, które przełącza webkitOverflowScrollingstyl. Sztuczka polega na tym, że ten styl jest wyłączony, mobilne Safari przechodzi do zwykłego przewijania i zapobiega nadmiernemu odbiciu - niestety nie jest w stanie anulować trwającego przeciągania. To złożone rozwiązanie śledzi również, onscrollgdy odbicie od góry sprawia, scrollTopże wartość ujemna może być śledzona. To rozwiązanie zostało przetestowane na iOS 12.1.1 i ma jedną wadę: podczas przyspieszania przewijania nadal występuje pojedyncze przeskakiwanie, ponieważ resetowanie stylu może nie anulować go natychmiast.
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)
}
}
}
poprawiona odpowiedź @Ben Bos i skomentowana przez @Tim
Ten CSS pomoże uniknąć problemów z przewijaniem i wydajnością przy ponownym renderowaniu CSS, ponieważ pozycja została zmieniona / niewielkie opóźnienie bez szerokości i wysokości
body,
html {
position: fixed;
width: 100%;
height: 100%
}
Dla tych z Was, którzy nie chcą pozbyć się odbijania, ale chcą tylko wiedzieć, kiedy się zatrzymają (na przykład, aby rozpocząć obliczenia odległości ekranu), mogą wykonać następujące czynności (kontener to przepełniony element kontenera):
<body><!-- the whole body can be scroll vertically --><article><my_gallery><!-- some picture gallery, can be scroll horizontally --></my_gallery></article></body>
Kiedy przewijam galerię, ciało zawsze przewija się (ruchy człowieka nie są tak naprawdę poziome), przez co moja galeria jest bezużyteczna.
Oto, co zrobiłem, gdy moja galeria zaczęła się przewijać
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
A kiedy moja galeria zakończy przewijanie ...
var html=jQuery('html');
html.css('overflow-y','scroll');
document.ontouchmove=function(e){returntrue;}
Używamy plików cookie i innych technologii śledzenia w celu poprawy komfortu przeglądania naszej witryny, aby wyświetlać spersonalizowane treści i ukierunkowane reklamy, analizować ruch w naszej witrynie, i zrozumieć, skąd pochodzą nasi goście.
Kontynuując, wyrażasz zgodę na korzystanie z plików cookie i innych technologii śledzenia oraz potwierdzasz, że masz co najmniej 16 lat lub zgodę rodzica lub opiekuna.