Entrance Chat Gallery Guilds Search Everyone Wiki Login Register

Welcome, Guest. Please login or register. - Thinking of joining the forum??
December 13, 2025 - @936.44 (what is this?)
Activity rating: Two Stars Posts & Arts: 16/1k.beats Unread Topics | Unread Replies | My Stuff | Random Topic | Recent Posts Start New Topic  Submit Art
News: ozwomp is requesting your location  :ozwomp: [Agree] Guild Events: There are no events!

+  MelonLand Forum
|-+  World Wild Web
| |-+  ✁ ∙ Web Crafting
| | |-+  ☔︎ ∙ I need Help!
| | | |-+  Trying to make a "Table of Contents" that only shows what you've read so far


« previous next »
Pages: [1] Print
Author Topic: Trying to make a "Table of Contents" that only shows what you've read so far  (Read 147 times)
rhoverdict
Newbie ⚓︎
*
View Profile WWW


"normal" is a relative term!
⛺︎ My Room
Itch.io: My Games

Guild Memberships:
Artifacts:
Joined 2025!
« on: December 10, 2025 @236.63 »

I'm trying to figure out if this is even possible, but I'm trying to put together a linear*, mostly-diary-entries-like kind of story as a side thing in my Neocity. I'd like to have a single "Table of Contents" page that readers can return to from any page that shows the pages they've already read, but not any they haven't read yet. However, I have absolutely no clue whether Javascript can manage this or if I'd just have to make enough variations of the ToC that each "diary entry" would link back to its own variation. Is using JS for this even feasible, or am I better off just making near-duplicate ToCs for every entry?

*linearity not guaranteed :grin:
Logged

┌────┬────┐
│     I     │   I  ı    │
├────┼────┤
│   ı  I    │    L     │
└────┴────┘


im here to make thingamabobs and play games, and i just lost The Game

any pronouns (including neos) (excluding it/its) but if you're feeling indecisive you can just use he/they for me it's fine :D
Dan Q
Sr. Member ⚓︎
****
View Profile WWWArt


I have no idea what I am doing
⛺︎ My Room
RSS: RSS

Guild Memberships:
Artifacts:
I met Dan Q on Melonland!
« Reply #1 on: December 10, 2025 @538.28 »

There are absolutely ways to do this. The best way for you depends on a variety of factors, but here's three you might consider. My approach is the opposite of yours - to do something that highlights only those not yet visited (my examples all strike-through or re-color "visited" pages in the table of contents), but the inverse is absolutely possible:

Option #1: CSS's a:visited pseudo-selector

The very simplest way that you can modify links that a user has already visited is with a CSS technique (that in turn inherits from a pre-CSS technique; this is really old). Something like this:


Code: css
#table-of-contents a:visited {
  color: pink;
}

That code will make all hyperlinks (within the element with id="table-of-contents">) that the user has ever visited pink. Note that for complicated privacy reasons you can't do much to change them (e.g. you can't completely hide them - in fact, you can only change the color and background-color IIRC!), but you can set their color to the same as the background color for much the same effect.

That's a nice simple one-liner that works for almost everybody and might be sufficient for your needs. It's also got the benefit that it doesn't matter how the user previously read your entry: the effect will be applied (e.g. if a user follows a deep link from some other site right to an entry, then leaves your site and does some other things, then comes to your table of contents for the first time... it'll still work because the :visited pseudo class is based on browser history!)

Option #2: Tracking link clicks with JS

The next-simplest approach would be to track when a table-of-contents link is clicked and save a "list" of links so-clicked to browser localStorage (a bit like cookies). Then, some other JavaScript can edit the links accordingly. I made you a CodePen you can copy/paste/adapt (try clicking some links and see them get crossed out; refresh the page and see that they still remember to be crossed-out). The essence of it is this:

1. When the page loads, check localStorage's "tracked-toc-links" storage for a list of links that have been visited.
2. Check each link in the "#table-of-contents"; if it's in the list, give it the CSS class "visited" (which styles it however you want; I'm using a strike-through effect).
3. When a link is clicked, give it the class "visited", AND add it to localStorage's "tracked-toc-links" list so the page remembers for the next visit.

For completeness/in case CodePen vanishes someday, here's the relevant JS:


Code: javascript
addEventListener('DOMContentLoaded', ()=>{
  // Get the table of contents:
  const toc = document.getElementById('table-of-contents');

  // Listen for clicks on its links:
  toc.addEventListener('click', e=>{
    // Reject clicks on non-links:
    const a = e.target;
    if( ! a || a.tagName !== 'A' ) return;

    // Mark the link as visited immediately (in case this was an open-in-new-tab):
    a.classList.add('visited');

    // Get the link destination:
    const destination = a.href;

    // Write to localStorage so the browser remembers what we visited:
    let trackedLinks = JSON.parse(localStorage.getItem('tracked-toc-links') || '[]'); // [] is the default value, if we've not tracked links before
    trackedLinks.push(destination); // add our link
    localStorage.setItem('tracked-toc-links', JSON.stringify(trackedLinks)); // write back to localStorage
  }, { capture: true, passive: true }); // capture=true so we get clicks on the child links; passive=true for performance (because we're never calling e.preventDefault())

  // when the page loads, check localStorage and update links accordingly -
  
  // Load previously clicked links list (or [] if none)
  const trackedLinks = JSON.parse(localStorage.getItem('tracked-toc-links') || '[]');
  
  // Find all potentially eligible links:
  const links = toc.querySelectorAll('a');
  
  // Check each link:
  for( link of links ) {
    // If it's NOT in the visited list, carry on:
    if( -1 === trackedLinks.indexOf(link.href) ) continue; // -1 is what indexOf returns if something is NOT found
    
    // This link must have been found! Mark it as visited:
    link.classList.add('visited');
  }
});

This approach tracks actual clicks on the links, which might be exactly what you want. It won't recognise when somebody follows a deep-link to an entry, only when they click from the table of contents. But if you'd like to pick up on deep links (using JS) too, you might want...

Option #3: Tracking visits with JS

This approach would be exactly the same as the one above, except you would (also?) add some code to each destination page that updates the localStorage too. This only works if each destination page is on the same domain as the table of contents (because localStorage can't be accessed cross-domain). You'd probably want some code like this on each page:


Code: javascript
// Load previously clicked links list (or [] if none)
const trackedLinks = JSON.parse(localStorage.getItem('tracked-toc-links') || '[]');

// check if the current page is already in the list:
if( -1 === trackedLinks.indexOf(location.href) ) {
  // it's not; so let's add it!
  trackedLinks.push(location.href);

  // then save back to localStorage
  localStorage.setItem('tracked-toc-links', JSON.stringify(trackedLinks));
}

With that JavaScript code running on each destination page, pages will be added to the visited list no matter how the user reaches them, even if they manually type in the URL, and that will be reflected in which ones get the 'visited' class in the table of contents page.

I hope that provides a useful starting point (or three useful starting points, of gradually increasing complexity!). Give a shout if you need more help!
Logged


Artifact Swap: I met Dan Q on Melonland!PolyamorousJoined 2025!Derp DoggoLurby
Pages: [1] Print 
« previous next »
 

Melonking.Net © Always and ever was! SMF 2.0.19 | SMF © 2021 | Privacy Notice | ~ Send Feedback ~ Forum Guide | Rules | RSS | WAP | Mobile


MelonLand Badges and Other Melon Sites!

MelonLand Project! Visit the MelonLand Forum! Support the Forum
Visit Melonking.Net! Visit the Gif Gallery! Pixel Sea TamaNOTchi