Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use intersection observer for highlighting active heading #1

Closed
rchrdnsh opened this issue Sep 15, 2021 · 2 comments
Closed
Labels
question Further information is requested

Comments

@rchrdnsh
Copy link

Hi XD

I have my own toc workflow for a sveltkit app i'm making and I have everything taken care of up until the intersection observer to highlight the current on screen headers in the toc...trying to figure out how to do it, but have no knowledge of intersection observers or using them with svelte...looking through your code and I'm not sure where that part begins...

In my toc I am looping through an array objects:

[
  { level: 1, heading: 'Frequencies' },
  { level: 1, heading: 'Notes' },
  { level: 2, heading: 'Equivalence' },
  { level: 2, heading: 'Pitch Classes' },
  { level: 1, heading: 'The Keyboard' },
  { level: 1, heading: 'Two Zones' },
  { level: 2, heading: 'Zone 1' },
  { level: 2, heading: 'Zone 2' },
  { level: 2, heading: 'Zone 1 + Zone 2' },
  // ...etc...
]

that is generated by a custom rehype plugin traversing some markdown...

I then loop through it in my toc.svelte file:

<div class='toc-box'>
  {#each headings as {level, heading}}
    <div class='heading'>
      <a class='toc-link'
        href={`/words/${slugify(title)}#${slugify(heading)}`}
      >
        <span class='toc-link-text'>{removeTags(heading)}</span>
      </a>
    </div>
  {/each}
</div>

...and everything is almost all good when the slugified href matches the current hash and I can click around and go to hash links and all that...still not perfect and prolly should use <ul>'s and <li>'s, making my own slugify() function and it doesn't quite work right yet, but these are other issues...

The last big piece of the toc puzzle is highlighting the toc headers that are currently in the viewport...just not sure how to go about it...

...I'm looking through your code and I'm not sure where that part begins and how to adapt it to my array of objects. I also have a REPL I've put together by lifting a codepen that works and trying to make it work with svelte, but can't figure it out...

Svelte REPL:
https://svelte.dev/repl/7006d7890b964928b8f72622a3d067ac?version=3.42.5

Original Codepen:

https://codepen.io/bramus/pen/ExaEqMJ

If you don't have time or interest for this no worries, totally understand, but if you have any thoughts that you would be willing to share I am all ears :-)

Thank you!

@janosh
Copy link
Owner

janosh commented Sep 16, 2021

Hey @rchrdnsh, identifying the currently viewport-intersecting heading in the ToC happens here:

([entry]) => {
activeHeading = entry.target as HTMLHeadingElement // assign intersecting node to activeHeading
},

The matching heading node is then assigned a class of active here:

class:active={activeHeading === nodes[idx]}

and styled here

nav > li.active {
color: var(--toc-active-color, orange);
}

Does that help/answer your question?

@janosh janosh added the question Further information is requested label Sep 16, 2021
@janosh janosh changed the title awesome work here...trying to figure out the intersection observer part for my own use case... How to use intersection observer for highlighting active heading Sep 16, 2021
@janosh
Copy link
Owner

janosh commented Oct 7, 2021

Closing for now. Please reopen if questions remain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants