Kérjük, vegye figyelembe, hogy ez a blogbejegyzés 2015 júniusában jelent meg, így attól függően, hogy mikor olvassa el, bizonyos részei elavultak lehetnek. Sajnos nem mindig tudom ezeket a bejegyzéseket teljesen naprakészen tartani, hogy biztosítsam az információk pontosságát.
- Saját tesztoldalam
- Az alapértelmezett viselkedés megértése
- Megérteni, mit csinál a "-webkit-overflow-scrolling" CSS-szabály
- A felhasználónak várnia kell, amíg a gumis hatás véget ér.
- Hogyan lehet megakadályozni, hogy a háttéroldal görgessen
- Hogyan lehet megakadályozni, hogy a háttéroldal túlzottan görgessen
- Hogyan lehet megakadályozni a túlgörgetést a háttéroldalra
- Az oldal teljes forráskódja
Az iOS-es Safari legújabb görgetési problémájának megoldása érdekében kénytelen voltam létrehozni egy saját, egyszerű tesztoldalt, majd az interneten talált információkat és különböző kombinációkat alkalmazni, hogy megpróbáljam megoldani a problémát.
Az alábbiakban egy rövid áttekintést talál arról, amit ebben a folyamatban felfedeztem.
Saját tesztoldalam
A tesztoldalam meglehetősen egyszerű volt. Az oldal reprezentációja egy statikus divben elhelyezett mintadatokat tartalmazott, és ehhez egy rögzített div is tartozott, amely az oldal fölött elhelyezkedő menüt ábrázolta, így nézett ki.
Az oldal teljes forráskódja megtalálható ennek a blogbejegyzésnek a végén.
Az alapértelmezett viselkedés megértése
Az első dolog, amit tettem, az volt, hogy megértsem az iOS-en futó Safari alapértelmezett viselkedését. A legszembetűnőbb megfigyelés az volt, hogy amikor a menü aljáig görgetsz, az oldal tartalma egy gumis hatásként jelentkezik – ez egy beépített funkció a Safariban.
Ugyanaz történt, amikor a menü tetejére görgettem.
Azonban az első problémám az volt, hogy ha folyamatosan görgetsz a tetejére vagy a legalsó részére, a Safari renderelési hibákat mutat a háttéroldalon és a menüben is.
Nem vagyok benne biztos, miért, de úgy sejtem, köze van a gumis visszapattanó hatáshoz.
Megérteni, mit csinál a "-webkit-overflow-scrolling" CSS-szabály
A következő lépés az volt, hogy alkalmaztam a -webkit-overflow-scrolling CSS-szabályt a menüre, amely lehetővé teszi a lendület-alapú görgetést.
Az alábbi képen látható módon a görgetés akkor is folytatódik, amikor az ujjam végighúzom.
De ez ráadásul gumis hatást is ad a görgetéskor a legfelső vagy a legalsó részre, ahogy az alábbiakban látható.
A felhasználónak várnia kell, amíg a gumis hatás véget ér.
A tesztelés során azt is észrevettem, hogy amíg a gumiszalag hatás zajlik, a felhasználó nem tud fókuszt váltani egy másik elemre, amíg az animáció teljesen be nem fejeződik.
Az alábbi példában először a háttéroldalt görgetem, majd gyorsan megpróbálom a menüt görgetni, de végül a háttéroldal görgetését folytatom.
Azonban, ha egy kicsit várok, hogy véget érjen a hatás, utána már tudok görgetni a menüt.
Hogyan lehet megakadályozni, hogy a háttéroldal görgessen
A tesztelés során azt is észrevettem, hogy a gumis hatás zajlása közben a felhasználó nem tud fókuszt váltani egy másik elemre, amíg az animáció teljesen be nem fejeződik.
A Stack Overflow oldalán található válasz alapján biztosítható, hogy a disable-scrolling osztályú elemek ne hajtsák végre az alapértelmezett görgetési műveletet, amikor a touchmove esemény aktiválódik.
document.ontouchmove = function(event) {
var isTouchMoveAllowed = true,
target = event.target;
while (target !== null) {
if (target.classList && target.classList.contains('disable-scrolling')) {
isTouchMoveAllowed = false;
break;
}
target = target.parentNode;
}
if (!isTouchMoveAllowed) {
event.preventDefault();
}
};
Ezután adja hozzá a disable-scrolling osztályt az oldal div-jéhez:
<div class="page disable-scrolling">
Ez részben működik, de alaposabb tesztelés szerint a háttéroldal néha még mindig görgethető lehet, amikor a menü legfelső vagy legalsó széléhez érünk.
Hogyan lehet megakadályozni, hogy a háttéroldal túlzottan görgessen
Ezzel a javítás megakadályozható a túlgörgetés. Ez azt jelenti, hogy amikor egy elemet a legfelső vagy a legalsó pontra görgetnek, a görgetés nem terjed ki a testre.
Ennek eredményeként az oldal nem görgethető, ami megakadályozza a gumírozott görgetési hatás megjelenését.
function removeIOSRubberEffect(element) {
element.addEventListener("touchstart", function() {
var top = element.scrollTop,
totalScroll = element.scrollHeight,
currentScroll = top + element.offsetHeight;
if (top === 0) {
element.scrollTop = 1;
} else if (currentScroll === totalScroll) {
element.scrollTop = top - 1;
}
});
}
removeIOSRubberEffect(document.querySelector(".scrollable"));
Ez a JavaScript-szkript megakadályozza, hogy az elem elérje a legfelső vagy a legalsó határt, és mindössze 1 pixellel tartja távol tőle.
Ha a görgetési pozíció soha nem éri el az abszolút felső vagy alsó határt, a túlhúzás soha nem fordul elő.
Hogyan lehet megakadályozni a túlgörgetést a háttéroldalra
Ha szeretnéd eltávolítani a gumírozott görgetési hatást a menüből – akár esztétikai okokból, vagy mert, mint az én esetemben, további renderelési problémákat okozott – egyszerűen távolítsd el a -webkit-overflow-scrolling CSS-szabályt.
Az alábbiakban látható, hogy a sima görgetés lendülete is elveszik.
Az oldal teljes forráskódja
Az oldal teljes forráskódja itt található.
<!-- License MIT, Author Special Agent Squeaky (specialagentsqueaky.com) --> <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="minimum-scale=1.0, width=device-width, maximum-scale=1.0, user-scalable=no, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style> .page{ font-size: 24px; overflow: scroll; } .menu{ position: fixed; top: 0; bottom: 0; left: 0; width: 80%; background: gray; z-index: 1; font-size: 10px; overflow: scroll; /* uncomment to get smooth momentum scroll, but also a rubber band effect */ /*-webkit-overflow-scrolling: touch;*/ } .menu-item{ padding: 10px; background: darkgray; font-size: 24px; } </style>
</head>
<body>
<div class="menu scrollable">
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
<div class="menu-item">hello world</div>
</div>
<div class="page disable-scrolling">
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and scrambled it to make a type
specimen book. It has survived not only five centuries, but also the leap into
electronic typesetting, remaining essentially unchanged. It was popularised in
the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</div>
<script>
document.ontouchmove = function(event) {
var isTouchMoveAllowed = true,
target = event.target;
while (target !== null) {
if (target.classList && target.classList.contains('disable-scrolling')) {
isTouchMoveAllowed = false;
break;
}
target = target.parentNode;
}
if (!isTouchMoveAllowed) {
event.preventDefault();
}
};
function removeIOSRubberEffect(element) {
element.addEventListener("touchstart", function() {
var top = element.scrollTop,
totalScroll = element.scrollHeight,
currentScroll = top + element.offsetHeight;
if (top === 0) {
element.scrollTop = 1;
} else if (currentScroll === totalScroll) {
element.scrollTop = top - 1;
}
});
}
removeIOSRubberEffect(document.querySelector(".scrollable"));
</script>
</body>
</html>