ScrollSpy

Beef

Pork

Lamb

Somethin

Pork

🥩

User scrolled to 'pork'

User scrolled to the 'Pork' section, scrollSpy detects this and

highlight the appropriate link in the navigation bar.

Cut

Ok, but how to do it?

Idea #1 - Control Line

Beef

Pork

Lamb

Pork

🥩

Parents

Control line

Somethin

Beef

Pork

Lamb

Pork

🥩

'top' is over the control line

Somethin

'bottom' is under

Detection

const { height, top } =
    document.getElementById('pork')
        .getBoundingClientRect();

const bottom = top + height;

Beef

Pork

Lamb

Pork

🥩

what if line would be between two parent blocks? Or under the last one?

Somethin

Issue

Link is not active

Idea #2 - Control Area

Beef

Pork

Lamb

Pork

🥩

Control zone

Somethin

Detection #1

Beef

Pork

Lamb

Pork

🥩

Detects income

Somethin

Detection #2

Beef

Pork

Lamb

Pork

🥩

Detects outcome

Somethin

Detection #3

Beef

Pork

Lamb

Pork

🥩

Detects situation

with two nodes inside & selects the last one

Somethin

* control area must be bigger than possible margins

Problem of last node

Beef

Pork

Lamb

Lamb

🥩

Somethin

Something

🥩

Footer

Actually last link should be highlighted

But it's impossible to scroll more, as we already reached the footer

Buffer area

Beef

Pork

Lamb

Lamb

🥩

Somethin

Something

🥩

Footer

Buffer zone. When user reach it, last link becomes active.

Formula

// Max Page Height
const body = document.body;
const html = document.documentElement;
const max = Math.max(
  body.scrollHeight,
  body.offsetHeight,                   
  html.clientHeight,
  html.scrollHeight,
  html.offsetHeight);
  
if (max - scrollY < window.innerHeight + BUFFER_ZONE_HEIGHT) {
  currentElement = categoriesObj[categoriesObj.length - 1].id;
}

ScrollSpy

By Serge Zdobnov

ScrollSpy

How to create your own scrollSpy. Not perfect and not the best one, but with minimal cost.

  • 398