See postitus on juunist 2015 – osad detailid võivad olla vananenud.
- Minu testilehekülg
- Vaikimisi käitumise mõistmine
- Mõistke, mida teeb CSS-i reegel "-webkit-overflow-scrolling"
- Kasutaja peab ootama, kuni kummibändi efekt lõpeb
- Kuidas vältida taustalehe kerimist
- Kuidas vältida taustalehe liigset kerimist
- Kuidas vältida liigset kerimist taustalehele
- Kogu lehekülje lähtekood
Et lahendada hiljutine kerimisprobleem Safari'ga iOS-il, pidin looma oma lihtsa testilehe ning seejärel rakendama kõiki internetist leitud teavet ja erinevaid kombinatsioone, mida leidsin, et probleemi lahendada.
Allpool on lühike ülevaade sellest, mida ma selle protsessi käigus avastasin.
Minu testilehekülg
Minu testileht oli üsna lihtne. See koosnes näidistest andmetest staatilises div-elemendis, mis esindas lehte, ning lisaks oli fikseeritud div, mis esindas lehe kohal paiknevat ülekatvat menüüd, nagu siin.
Selle lehe täielik lähtekood on selle blogipostituse lõpus.
Vaikimisi käitumise mõistmine
Esimene asi, mida ma tegin, oli püüda mõista iOS-i Safari vaikimisi käitumist. Kõige märkimatavam tähelepanek oli see, et kui kerite menüü lõpuni, ilmub lehekülje kehal rubber-band effekt — see on Safari jaoks kõvakooditud omadus.
Sama asi juhtus, kui kerisid menüü ülaossa.
Kuid esimene probleem, mida märkasin, oli see, et kui kerite pidevalt kõige ülemisse või alumisse serva, hakkab Safari kuvama renderdamisvigu nii taustalehel kui ka menüüs.
Ma ei ole kindel, miks, kuid ma kahtlustan, et sellel on midagi pistmist kummipaela funktsiooniga.
Mõistke, mida teeb CSS-i reegel "-webkit-overflow-scrolling"
Järgmiseks rakendasin menüüle CSS-i reegli -webkit-overflow-scrolling, mis lubab momentumi-põhist kerimist.
Nagu alloleval pildil näha on, jätkub kerimine isegi pärast seda, kui libistan sõrmega.
Kuid see lisab ka kummiefekti, kui kerid kõige ülemise või alumise servani, nagu allpool näidatud.
Kasutaja peab ootama, kuni kummibändi efekt lõpeb
Testimise ajal märkasin ka, et kui kummipaela efekt on käimas, ei saa kasutaja fookust teisele elemendile suunata, kuni animatsioon on täielikult lõpule jõudnud.
Allolevas näites kerin esmalt taustalehte ja seejärel püüan kiiresti kerida menüüd, kuid lõpuks jätkan hoopis taustalehe kerimist.
Kuid kui ma ootan hetkeks, kuni efekt lõpeb, võin seejärel kerida menüüd.
Kuidas vältida taustalehe kerimist
Testimise käigus märkasin ka, et kui elastne efekt on pooleli, ei saa kasutaja fookust teisele elemendile nihutada enne, kui animatsioon on täielikult lõppenud.
Sellele Stack Overflow'i vastusele põhinedes võite veenduda, et elemendid, millel on disable-scrolling, ei soorita nende vaikimisi kerimise toimingut, kui touchmove sündmus käivitub.
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();
}
};
Ja seejärel rakendage disable-scrolling klass lehe divile:
<div class="page disable-scrolling">
See töötab üsna hästi, kuid põhjalikum testimine näitab, et taustaleht võib mõnikord ikkagi kerida, kui jõuad menüü väga ülaossa või alumisse serva.
Kuidas vältida taustalehe liigset kerimist
Selle paranduse rakendamisega on võimalik vältida liigset kerimist. See tähendab, et kui element on keritud selle kõige ülemise või alumise piirini, kerimine ei liigu edasi keha suunas.
Seetõttu on keha kerimine keelatud, mis omakorda peatab ka rubber-band-efekti tekkimise.
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"));
See JavaScripti koodilõik takistab elementi kunagi jõudmast väga ülemisele või alumisele servale, hoides seda vaid 1 piksli kaugusel.
Kui kerimise asukoht ei ulatu kunagi absoluutse üla- või alumise servani, ei saa ülekerimist kunagi tekkida.
Kuidas vältida liigset kerimist taustalehele
Kui soovite menüüs eemaldada iOS-i kummiga tagasitõmbumise efekti — kas esteetilistel põhjustel või sest minu puhul tekitas see täiendavaid renderdamise tõrkeid — lihtsalt eemaldage -webkit-overflow-scrolling CSS reegel.
Kuid nagu allpool näete, kaotate ka sujuva kerimise hoogu.
Kogu lehekülje lähtekood
Siin on lehe täielik lähtekood.
<!-- 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>