9 Mayıs 2023

Sayfa Kaydırma(Scrolling)

Kaydırma olayları, bir sayfada veya öğe kaydırmada tepki vermeyi sağlar. Burada yapabileceğimiz epeyce iyi şeyler var.

Örneğin:

  • Kullanıcının belgede nerede olduğuna bağlı olarak ek kontrolleri veya bilgileri gösterin / gizleyin…
  • Kullanıcı sayfanın sonuna kadar aşağı kaydırdığında daha fazla veri yükleyin.

Küçük bir kaydırma örneği:

window.addEventListener('scroll', function() {
  document.getElementById('showScroll').innerHTML = pageYOffset + 'px';
});

İşlemde:

Mevcut kaydırma = scroll the window

scroll elementi hem window ta hem de kaydırılabilir elementlerde çalışır.

Kaydırmayı Önlemek

Bir şeyi nasıl kaydırılamaz hale getiririz? onscroll dinleyicisinde event.preventDefault() kullanarak kaydırmayı engelleyemiyoruz çünkü kaydırma zaten gerçekleştikten sonra tetiklenir.

Ancak event.preventDefault() ile , kaydırmaya neden olan bir olayda kaydırmayı engelleyebiliriz .

Örneğin:

  • wheel olayı – farenin tekerliği ile veya “kayan bir dokunmatik alan” yani touchpad de aynı görevi üstlenir).
  • keydown olayı için pageUp ve pageDown.

Bu olaylara bir olay işleyicisi (event handler) ve bunun içine event.preventDefault() eklersek, kaydırma başlamaz.

Bazen bu size yardımcı olabilir ancak bir şeyi kaydırılamaz hale getirmek için CSS kullanmak daha güvenilirdir mesela overflow özelliği gibi.

İşte onscroll ile çözebileceğiniz veya uygulamaları görmek için inceleyebileceğiniz birkaç görev.

Görevler

önem: 5

Sonsuz bir sayfa oluşturun. Ziyaretçi sayfayı sonuna kadar kaydırdığında metnin sonuna otomatik olarak güncel tarih-saat eklenir (böylece ziyaretçi daha fazla kaydırabilir).

Örnekteki gibi:

Lütfen kaydırmanın iki önemli özelliğine dikkat edin:

  1. Kaydırma “esnektir”. Bazı tarayıcılarda / cihazlarda sayfa başlangıcından veya sonundan biraz öteye kaydırabiliriz (altında boşluk görüntülenir ardından otomatik olarak normale “geri döner”).
  2. Kaydırma “belirsizdir”. Sayfa sonuna kaydırdığımızda gerçek sayfanın altından 0-50 piksel kadar uzakta olabiliriz.

Dolayısıyla “sonuna kadar kaydırma” ifadesi, ziyaretçinin sayfa sonuna en fazla 100 piksel uzakta olduğu anlamına gelmelidir.

Not: Gerçek hayatta “daha fazla mesaj” veya “daha fazla ürün” göstermek isteyebiliriz.

Görevler için korunaklı alan aç.

The core of the solution is a function that adds more dates to the page (or loads more stuff in real-life) while we’re at the page end.

We can call it immediately and add as a window.onscroll handler.

The most important question is: “How do we detect that the page is scrolled to bottom?”

Let’s use window-relative coordinates.

The document is represented (and contained) within <html> tag, that is document.documentElement.

We can get window-relative coordinates of the whole document as document.documentElement.getBoundingClientRect(). And the bottom property will be window-relative coordinate of the document end.

For instance, if the height of the whole HTML document is 2000px, then:

// When we're on the top of the page
// window-relative top = 0
document.documentElement.getBoundingClientRect().top = 0

// window-relative bottom = 2000
// the document is long, so that is probably far beyond the window bottom
document.documentElement.getBoundingClientRect().bottom = 2000

If we scroll 500px below, then:

// document top is above the window 500px
document.documentElement.getBoundingClientRect().top = -500
// document bottom is 500px closer
document.documentElement.getBoundingClientRect().bottom = 1500

When we scroll till the end, assuming that the window height is 600px:

// document top is above the window 1400px
document.documentElement.getBoundingClientRect().top = -1400
// document bottom is below the window 600px
document.documentElement.getBoundingClientRect().bottom = 600

Please note that the bottom can’t be 0, because it never reaches the window top. The lowest limit of the bottom coordinate is the window height, we can’t scroll it any more up.

And the window height is document.documentElement.clientHeight.

We want the document bottom be no more than 100px away from it.

So here’s the function:

function populate() {
  while(true) {
    // document bottom
    let windowRelativeBottom = document.documentElement.getBoundingClientRect().bottom;

    // if it's greater than window height + 100px, then we're not at the page back
    // (see examples above, big bottom means we need to scroll more)
    if (windowRelativeBottom > document.documentElement.clientHeight + 100) break;

    // otherwise let's add more data
    document.body.insertAdjacentHTML("beforeend", `<p>Date: ${new Date()}</p>`);
  }
}

Çözümü korunaklı alanda aç.

önem: 5

Create a “to the top” button to help with page scrolling.

It should work like this:

  • While the page is not scrolled down at least for the window height – it’s invisible.
  • When the page is scrolled down more than the window height – there appears an “upwards” arrow in the left-top corner. If the page is scrolled back, it disappears.
  • When the arrow is clicked, the page scrolls to the top.

Like this:

Görevler için korunaklı alan aç.

önem: 4

Let’s say we have a slow-speed client and want to save their mobile traffic.

For that purpose we decide not to show images immediately, but rather replace them with placeholders, like this:

<img src="placeholder.svg" width="128" height="128" data-src="real.jpg">

So, initially all images are placeholder.svg. When the page scrolls to the position where the user can see the image – we change src to the one in data-src, and so the image loads.

Here’s an example in iframe:

Scroll it to see images load “on-demand”.

Requirements:

  • When the page loads, those images that are on-screen should load immediately, prior to any scrolling.
  • Some images may be regular, without data-src. The code should not touch them.
  • Once an image is loaded, it should not reload any more when scrolled in/out.

P.S. If you can, make a more advanced solution that would “preload” images that are one page below/after the current position.

P.P.S. Only vertical scroll is to be handled, no horizontal scrolling.

Görevler için korunaklı alan aç.

The onscroll handler should check which images are visible and show them.

We also may want to run it when the page loads, to detect immediately visible images prior to any scrolling and load them.

If we put it at the <body> bottom, then it runs when the page content is loaded.

// ...the page content is above...

function isVisible(elem) {

  let coords = elem.getBoundingClientRect();

  let windowHeight = document.documentElement.clientHeight;

  // top elem edge is visible OR bottom elem edge is visible
  let topVisible = coords.top > 0 && coords.top < windowHeight;
  let bottomVisible = coords.bottom < windowHeight && coords.bottom > 0;

  return topVisible || bottomVisible;
}

showVisible();
window.onscroll = showVisible;

For visible images we can take img.dataset.src and assign it to img.src (if not did it yet).

P.S. The solution also has a variant of isVisible that “pre-loads” images that are within 1 page above/below (the page height is document.documentElement.clientHeight).

Çözümü korunaklı alanda aç.

Eğitim haritası