Profesyonel İnternet Bağımlısı • Oyun Tutkunu • Teknoloji Yaratıcısı
Profesyonel İnternet Bağımlısı • Oyun Tutkunu • Teknoloji Yaratıcısı

iOS Safari'nın elastik kaydırmasıyla ilgili öğrendiğim altı şey

iOS'ta Safari'deki kaydırma sorununu çözmek için kendi basit test sayfamı oluşturmaya mecbur kaldım!
Bu sayfa, kolaylık sağlamak amacıyla son derece istekli yapay zeka stajyerlerim tarafından İngilizceden çevrilmiştir. Hâlâ öğrenme aşamasında oldukları için birkaç hata gözden kaçmış olabilir. En doğru bilgi için lütfen İngilizce versiyona bakın.
Ev Blog iOS Safari'nın elastik kaydırmasıyla ilgili öğrendiğim altı şey

Bu blog yazısının Haziran 2015'te yayınlandığını, dolayısıyla ne zaman okuduğunuza bağlı olarak bazı bölümlerinin güncelliğini yitirebileceğini lütfen unutmayın. Maalesef, bilgilerin doğru kalmasını sağlamak için bu yazıları her zaman tam olarak güncel tutamıyorum.

iOS'ta Safari'de yaşanan son bir kaydırma sorununu çözebilmek için kendi basit test sayfamı oluşturmam gerekti ve ardından sorunu çözmeye çalışmak için internette bulabildiğim tüm bilgiler ve kombinasyonları uygulamaya çalıştım.

Bu süreçte keşfettiklerimin kısa bir özeti aşağıdadır.

Test Sayfam

Test sayfam oldukça basitti. Sayfayı temsil etmek için statik bir div içinde sahte veriler vardı ve sayfanın üzerinde yer alan bir menüyü temsil eden sabit bir div de bulunuyordu; şu şekildeydi.

iOS Safari'de açılmış HTML yan menüsünün ekran görüntüsü

Sayfaya ait tüm kaynak kodu bu blog yazısının en altında bulunabilir.

Varsayılan Davranışı Anlamak

İlk yaptığım şey, iOS'taki Safari'nin varsayılan davranışını anlamaya çalışmaktı. En dikkat çekici gözlem ise, menünün en altına kadar kaydırdığınızda sayfanın gövdesinin bir lastik bant etkisi göstermesiydi - Safari'de yerleşik olarak kodlanmış bir özelliktir.

Sayfanın altında, iOS Safari'de sorunlu lastik bant etkisini gösteren animasyonlu bir ekran görüntüsü

Menünün en üstüne kaydırırken de aynı şey oldu.

sayfanın üst kısmında iOS Safari'de yaşanan sorunlu lastik bant etkisinin bir animasyonlu ekran görüntüsü

Ancak fark ettiğim ilk sorun, sürekli olarak en üste ya da en altta kadar kaydırırsanız Safari'nin hem arka plan sayfasında hem de menüde render hataları göstermeye başlamasıydı.

Nedenini tam olarak bilmiyorum, ama bunun lastik bant özelliğiyle ilgili olduğuna inanıyorum.

Sayfanın altında bulunan, iOS Safari'deki sorunla ilgili animasyonlu bir ekran görüntüsü

"-webkit-overflow-scrolling" CSS Kuralının Ne Yaptığını Anlamak

Bir sonraki adım olarak menüye -webkit-overflow-scrolling CSS kuralını uyguladım; bu, momentum tabanlı kaydırmayı etkinleştirir.

Aşağıdaki resimde gösterildiği gibi, parmağımla kaydırdıktan sonra bile kaydırma devam ediyor.

iOS Safari'de momentumlu kaydırma sorununu gösteriyor

Ama en üste ya da en alta kaydırırken de lastik bant etkisi oluşur; aşağıda gösterildiği gibi.

iOS Safari'de momentum tabanlı kaydırma sorununu lastik bant etkisiyle gösteriyor

Kullanıcı, lastik bant etkisi bitene kadar beklemeli

Testlerim sırasında, kauçuk bant etkisi devam ederken kullanıcının animasyon tamamen tamamlanana kadar başka bir öğeye odaklanamayacağını da fark ettim.

Aşağıdaki örnekte önce arka plan sayfasını kaydırıyorum, sonra menüyü hızlıca kaydırmaya çalışıyorum; ancak sonunda arka plan sayfasını kaydırmaya devam ediyorum.

iOS Safari'de arka sayfanın kaydırıldığı gösteriliyor

Ancak efektin bitmesini bir an beklersem menüyü kaydırmaya başlayabilirim.

iOS Safari'de lastik bant etkisinin tamamlanmasını beklerken gösteriyoruz

Arka Plan Sayfasının Kaydırılmasını Nasıl Önlersiniz

Testlerim sırasında, lastik bant etkisi devam ederken kullanıcı başka bir öğeye odaklanamıyor ve animasyon tamamen bitene kadar bu durum sürüyor.

Stack Overflow'daki bu yanıt temel alınarak, Stack Overflow ile, disable-scrolling sınıfına sahip öğelerin touchmove olayı tetiklendiğinde varsayılan kaydırma işlemini gerçekleştirmemelerini sağlayabilirsiniz.

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(); } };

Ve sonra disable-scrolling sınıfını sayfa içindeki div'e uygulayın:

<div class="page disable-scrolling">

Bu şekilde çalışıyor, ancak daha kapsamlı testler, menünün en üstüne veya en altına ulaştığınızda arka plan sayfasının hâlâ bazen kaydırılabileceğini gösteriyor.

Arka planın hâlâ kaydırıldığını gösteriyor

Arka sayfaya aşırı kaydırmayı nasıl engellersiniz?

Bu çözüm ile artık 'overscroll'ı önlemek mümkün hale geliyor. Bu, bir öğe en üstte ya da en altta kaydırıldığında kaydırmanın sayfa içeriğine geçmemesi anlamına gelir.

Sonuç olarak sayfa kaydırılamaz hâle gelir ve bu da lastik bant etkisinin oluşmasını engeller.

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"));

Bu JavaScript kod parçacığının yaptığı iş, öğenin en üstte ya da en altta tamamen ulaşmasını engellemek için onu sadece 1 piksel uzağa tutmaktır.

Kaydırma konumu mutlak en üst veya en alt sınırına hiç ulaşmazsa, aşırı kaydırma asla meydana gelmez.

En üst noktaya ya da en uç noktaya hiç gitmeden aşırı kaydırmayı engellemeyi gösteren bir demo

Arka Sayfaya Aşırı Kaydırmayı Nasıl Önlersiniz?

Menüden kauçuk bant etkisini kaldırmak istersen — estetik nedenlerle veya benim durumumda olduğu gibi ek render hatalarına yol açtığı için — sadece -webkit-overflow-scrolling CSS kuralını kaldır.

Ancak aşağıda gördüğünüz gibi akıcı kaydırma hareketini de kaybediyorsunuz.

iOS Safari'de rubberbanding'i önlemeye yönelik tam bir demo

Tüm Sayfa Kaynak Kodu

Sayfanın tüm kaynak kodu burada.

<!-- 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>

Special Agent Squeaky tarafından yazıldı. İlk yayın tarihi 2015-06-10. Son güncelleme tarihi 2015-06-10.

📺 Squeaky'nin en yeni videosunu izle!

Canlı yayınınıza basit gerçek zamanlı altyazılar nasıl eklenir?