Huomioithan, että tämä blogipostaus on julkaistu kesäkuussa 2015, joten jotkin tiedot voivat olla muuttuneet sen jälkeen. En aina ehdi päivittää kaikkia postauksia heti.
- Oma testisivuni
- Oletuskäyttäytymisen ymmärtäminen
- Mitä -webkit-overflow-scrolling CSS-sääntö tekee
- Käyttäjän täytyy odottaa, kunnes kuminauhaefekti päättyy.
- Kuinka estää taustasivun vierittäminen
- Kuinka estää taustasivun liiallinen vieritys
- Kuinka estää liiallinen vieritys taustasivulle
- Koko sivun lähdekoodi
Jotta voisin korjata äskettäisen vieritysongelman iOS:n Safari-selaimessa, minun piti luoda oma yksinkertainen testisivuni ja soveltaa sitten Internetistä löytämääni tietoa sekä erilaisten yhdistelmien avulla ongelman ratkaisemiseksi.
Alla on lyhyt yhteenveto siitä, mitä löysin tämän prosessin aikana.
Oma testisivuni
Testisivuni oli melko yksinkertainen. Siinä oli staattiseen diviin sijoitettua mock-dataa kuvaamaan sivua sekä sivun yläpuolella olevaa kiinteää diviä, jolla esitettiin päällekkäistä valikkoa, kuten tässä.
Sivun koko lähdekoodi löytyy tämän blogikirjoituksen lopusta.
Oletuskäyttäytymisen ymmärtäminen
Ensimmäiseksi yritin ymmärtää Safarin oletuskäyttäytymistä iOS:llä. Merkittävin havainto oli se, että kun vierität valikon aivan loppuun asti, sivun runko kokee kumivaikutuksen – Safarin kovakoodattu ominaisuus.
Sama asia tapahtui, kun vieritimme valikon aivan yläreunaan.
Kuitenkin ensimmäinen havaitsemani ongelma oli, että jos vierität jatkuvasti aivan yläreunaan tai alareunaan asti, Safari alkaa näyttää renderöintivirheitä sekä taustasivulla että valikossa.
En ole varma siitä, miksi, mutta epäilen, että sillä on jotain tekemistä kuminauhaominaisuuden kanssa.
Mitä -webkit-overflow-scrolling CSS-sääntö tekee
Seuraavaksi sovelsin -webkit-overflow-scrolling CSS-sääntöä valikkoon, joka mahdollistaa momentum-pohjaisen vierityksen.
Alla olevan kuvan mukaan vieritys jatkuu sormen pyyhkäisyn jälkeen.
Mutta se tuo myös kuminauhamaisen vaikutuksen, kun vierität aivan yläreunaan tai alareunaan, kuten alla näkyy.
Käyttäjän täytyy odottaa, kunnes kuminauhaefekti päättyy.
Testaukseni aikana huomasin myös, että kun kuminauha-efekti on käynnissä, käyttäjä ei voi siirtää kohdistusta toiseen elementtiin ennen kuin animaatio on täysin valmis.
Alla olevassa esimerkissä vieritän ensin taustasivua ja yritän sitten nopeasti vierittää valikkoa, mutta päädyn lopulta jatkamaan taustasivun vierittämistä.
Jos kuitenkin odotan hetken, jotta efekti ehtii loppua, voin sitten alkaa selata valikkoa.
Kuinka estää taustasivun vierittäminen
Testauksen aikana huomasin myös, että kun kumibändivaikutus on käynnissä, käyttäjä ei voi siirtää kohdistusta toiseen elementtiin ennen kuin animaatio on täysin valmis.
Perustuen tähän Stack Overflow, voit varmistaa, että niillä elementeillä, joilla on disable-scrolling, ei ole oletuksena vieritystoimintoa, kun touchmove-tapahtuma laukaistaan.
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 sitten sovella disable-scrolling-luokkaa sivun diviin:
<div class="page disable-scrolling">
Tämä toimii jollain tavalla, mutta laajemman testauksen mukaan taustasivu voi silti toisinaan vierittää sivua, kun saavut valikon aivan ylä- tai alareunaan.
Kuinka estää taustasivun liiallinen vieritys
Ottamalla tämän korjauksen käyttöön voidaan estää "overscrolling". Tämä tarkoittaa, että kun elementti on vieritetty aivan ylä- tai alareunaan asti, vieritys ei siirry sivun runkoon.
Sen seurauksena sivua ei voi vierittää, mikä estää myös elastisen palautumisefektin syntymisen.
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"));
Tämä JavaScript-koodinpätkä estää elementtiä pääsemästä koskaan aivan yläreunaan tai alareunaan pitämällä sen vain 1 pikselin päässä.
Jos vierityksen sijainti ei koskaan saavuta absoluuttista ylintä tai alinta kohtaa, ylivuoto ei ole mahdollista.
Kuinka estää liiallinen vieritys taustasivulle
Jos haluat poistaa valikon jousivaikutuksen – joko esteettisistä syistä tai koska, kuten omassa tapauksessani, se aiheutti lisärenderöintivirheitä – poista yksinkertaisesti -webkit-overflow-scrolling CSS-sääntö.
Kuten alla näet, menetät myös sen sujuvan vierityksen dynamiikan.
Koko sivun lähdekoodi
Tässä on tämän sivun koko lähdekoodi.
<!-- 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>