Atkreipkite dėmesį, kad šis tinklaraščio įrašas buvo paskelbtas 2015 m. birželio mėn., todėl, priklausomai nuo to, kada jį skaitysite, tam tikros dalys gali būti pasenusios. Deja, ne visada galiu atnaujinti šiuos įrašus, kad užtikrinčiau informacijos tikslumą.
- Mano testinis puslapis
- Supratimas apie numatytąjį elgesį
- Suprasti, ką daro CSS taisyklė „-webkit-overflow-scrolling“
- Vartotojui reikia palaukti, kol baigsis gumos juostos efektas
- Kaip užkirsti kelią foninio puslapio slinkimui
- Kaip užkirsti kelią fono puslapio perslinkimui
- Kaip išvengti peršokimo į foninį puslapį
- Viso puslapio šaltinio kodas
Kad išspręsčiau neseniai kilusią slinkimo problemą Safari naršyklėje iOS, buvau priverstas susikurti savo paprastą testinį puslapį ir tada pritaikyti visą informaciją bei visas kombinacijas, kurias radau internete, bandydamas išspręsti šią problemą.
Žemiau pateikiama trumpa apžvalga apie tai, ką atradau šio proceso metu.
Mano testinis puslapis
Mano testinis puslapis buvo gana paprastas. Jame buvo naudojami fiktyvūs duomenys statiniame „div“ elemente, kad atvaizduotų „puslapį“, o kartu – fiksuotas „div“ elementas, kuris virš puslapio vaizduoja perdengtą („overlay“) „meniu“, kaip šis.
Šio puslapio visą šaltinio kodą galima rasti šio tinklaraščio įrašo apačioje.
Supratimas apie numatytąjį elgesį
Pirmiausia aš stengiausi suprasti įprastą Safari elgesį iOS. Bene ryškiausias pastebėjimas buvo tas, kad nuslinkus iki meniu apačios, puslapio turinys rodė guminės juostos efektą – tai užkoduota Safari funkcija.
Tas pats įvyko, kai nuslinkome iki pat meniu viršaus.
Tačiau pirmoji pastebėta problema buvo ta, kad nuolat slenkant iki pat viršaus ar apačios, „Safari“ pradeda rodyti atvaizdavimo klaidas tiek fono puslapyje, tiek meniu.
Nesu tikras, kodėl, bet įtariu, kad tai turi ryšį su guminės juostos funkcija.
Suprasti, ką daro CSS taisyklė „-webkit-overflow-scrolling“
Kitas dalykas, kurį padariau, buvo taikyti -webkit-overflow-scrolling CSS taisyklę meniu, kuri leidžia slinkimą su pagreičiu.
Kaip matyti žemiau esančiame paveikslėlyje, slinkimas tęsiasi net ir kai braukiu pirštu.
Tačiau jis taip pat sukelia gumos efektą, kai slenkate iki pat viršaus ar apačios, kaip parodyta žemiau.
Vartotojui reikia palaukti, kol baigsis gumos juostos efektas
Atliekant testavimą taip pat pastebėjau, kad kol vyksta elastinio efekto (rubber-band) animacija, naudotojas negali perkelti fokuso į kitą elementą, kol animacija visiškai nesibaigs.
Žemiau pateiktame pavyzdyje iš pradžių nuslinkiu foninį puslapį, o tada greitai bandau nuslinkti meniu, bet vietoj to vis tiek toliau nuslinkiu foninį puslapį.
Tačiau jei palauksiu akimirką, kol efektas pasibaigs, galėsiu pradėti naršyti meniu.
Kaip užkirsti kelią foninio puslapio slinkimui
Testavimo metu taip pat pastebėjau, kad kol vyksta guminės juostos efekto animacija, vartotojas negali perjungti dėmesio į kitą elementą iki kol animacija visiškai nesibaigia.
Remiantis šiuo atsakymu iš Stack Overflow, galite užtikrinti, kad elementai su disable-scrolling neatliktų savo numatytojo slinkimo veiksmo kai įvyksta touchmove įvykis.
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();
}
};
Ir tada pritaikykite disable-scrolling klasę prie puslapio div elemento:
<div class="page disable-scrolling">
Šis sprendimas veikia gana gerai, tačiau išsamesni bandymai rodo, kad foninis puslapis vis dar kartais gali persislinkti, kai pasiekiate meniu viršų ar apačią.
Kaip užkirsti kelią fono puslapio perslinkimui
Taikydami šį pataisymą, galima užkirsti kelią „overscroll“ (viršijimo slinkimo) reiškiniui. Tai reiškia, kad kai elementas pasiekia savo viršų ar apačią, slinkimas neperžengia į dokumento kūną.
Taigi kūnas neleidžia slinktis, o tai taip pat užkerta kelią gumos juostos efekto atsiradimui.
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"));
Šis JavaScript fragmentas užtikrina, kad elementas niekada nepatektų į patį viršų ar į patį apačią, laikydamas jį vos vienu pikseliu nuo krašto.
Jei slinkimo pozicija niekada nepasiekia absoliutaus viršaus ar apačios, overscroll niekada neįvyks.
Kaip išvengti peršokimo į foninį puslapį
Jei norite pašalinti gumos juostos efektą iš meniu — ar dėl estetikos, ar dėl to, kad, kaip ir man, tai sukėlė papildomų renderavimo trikčių, tiesiog pašalinkite -webkit-overflow-scrolling CSS taisyklę.
Tačiau, kaip matote žemiau, taip pat prarandate sklandų slinkimo impulsą.
Viso puslapio šaltinio kodas
Štai visas puslapio šaltinio kodas.
<!-- 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>