docsy icon indicating copy to clipboard operation
docsy copied to clipboard

New Feature: Navigation indication on the right TOC

Open quickstar opened this issue 4 years ago โ€ข 24 comments

Hi

I think it would make sense to have a visual indication on which chapter on page the reader currently is.

The Airflow example has a nice implementation to showcase this feature. Bildschirmfoto am 2020-10-02 um 14 48 02

As one can see the chapter which the reader has scrolled to, is visually highlighted on the right.

I think such a feature would greatly enhance the usability of docsy in general. What do you think?

quickstar avatar Oct 02 '20 12:10 quickstar

Oh that is nice, especially for long pages. I like that the highlight automatically scrolls up and down as you scroll up and down the page. Anyone with the skills to implement this, please jump in (or chime in if you don't think it's useful).

LisaFC avatar Oct 02 '20 13:10 LisaFC

+1 from me. That's slick. This kind of feedback not only helps the reader understand where they're at, but also encourages exploration further down the page. Would love to see this in Docsy one day.

prdsoftware avatar Oct 02 '20 21:10 prdsoftware

Just wondering, as someone who doesn't know a great deal about the web tech: if Airflow, which is based on Docsy has this, what stands in the way of back-porting it to Docsy? I think this adds a bit of user friendliness.

Symbolics avatar Feb 09 '21 01:02 Symbolics

Hi, @Symbolics.๐Ÿ™‚ Unfortunately, though the style of the Airflow documentation is similar to the Docsy, it seems that Airflow documentation itself uses Sphinx (ref. airflow/docs at master ยท apache/airflow) instead of Docsy. Sphinx is yet another documentation tool written by Python so we cannot simply back-port it.

But I think your idea has a good point. if there is a Docsy website that has already implemented the side navigation somewhere, we could back-port it.

shuuji3 avatar Feb 09 '21 14:02 shuuji3

I see. I was confused because Airflow is listed as a customised Docsy example on the examples page. Perhaps it should be removed there, or a note added about it using both Docsy and Sphinx.

Symbolics avatar Feb 10 '21 01:02 Symbolics

As a general note, I think the impact that visual elements have on reader experience should not be underestimated. Even hard-core techo's know that it's about functionality, yet are still subconsciously affect by the way the pages look, and this affects overall project uptake.

Symbolics avatar Feb 10 '21 01:02 Symbolics

@Symbolics I'm sorry, I was wrong. The airflow documentation repository in the "example page" you pointed out uses Docsy certainly. I only saw another repository which is the source of the documentation of that repository.

After I investigated the repository, I found the implementation of this feature: https://github.com/apache/airflow-site/blob/master/landing-pages/src/js/progressTracking.js. To summarize, when users scroll a page, it calculates the current position and adds a "current" class to one of the sections to indicate the current place.

As a general note, I think the impact that visual elements have on reader experience should not be underestimated.

I agree. From my experience, I spend a lot of time reading documentation using the Docsy theme but sometimes lose my way because there is no indication of where I'm reading on the sidebar. Giving the context to users should improve the understandability of users.

shuuji3 avatar Feb 10 '21 10:02 shuuji3

Thanks @shuuji3 for taking the time to find the JS that the Airflow site is using for this feature! If I have time I'll see what would be involved in adding something similar to our right nav - or if anyone with more experience would like to have a go?

And yes, I agree that visual elements are important! I am a tech writer rather than a web designer and our first iteration was very focused on structure and getting the basic navigation setup (while not looking terrible!), I'd love to add more useful visual cues to the template.

LisaFC avatar Feb 10 '21 11:02 LisaFC

Thank you @LisaFC, I have a strong motivation for realizing this feature so I'd like to try to implement it! As a first step, as @quickstar suggested and I already investigated, I'll try to back-port the script used by the Airflow documentation and amend it for the default Docsy template. Is there any suggestion?

One question: if we add a new JavaScript file, which is the right place to put it: https://github.com/google/docsy/tree/master/assets/js or https://github.com/google/docsy/tree/master/static?

shuuji3 avatar Feb 10 '21 12:02 shuuji3

Oh that's great! Either directory will work (though I think with assets/ you can do more things to the JS, eg minify, as the files in assets/ can be processed further).

LisaFC avatar Feb 10 '21 18:02 LisaFC

Thanks for your advice! I'll try to implement it.

shuuji3 avatar Feb 12 '21 03:02 shuuji3

Hi @shuuji3 Pretty cool to see someone is investigating on this topic! Good luck, let me now if I can assist in any way.

quickstar avatar Feb 13 '21 08:02 quickstar

Thanks @quickstar ! I'd like to ask your help if I stuck somewhere.๐Ÿ™‚ Also, thanks for your starting out this issue.

shuuji3 avatar Feb 13 '21 08:02 shuuji3

@LisaFC @quickstar I've just created a draft PR to implement this feature. Sorry for the late! :pray: Could you please take a look at it and provide some feedback? Thank you. ๐Ÿ™‚

shuuji3 avatar Apr 08 '21 15:04 shuuji3

Hi all,

I added this myself in a new script I created. I saved the script as scrollspy.js in a static\js folder and then I referenced it partial\hooks\bodyend.html.

window.addEventListener("load", (event) => {
    createObserver();
}, false);

function createObserver() {
    let observer;

    let options = {
        root: null,
        rootMargin: '0px 5px -90%'
    };

    observer = new IntersectionObserver((entries, observer) => {
        entries.forEach(entry => {
            const id = entry.target.getAttribute('id');
            if (entry.intersectionRatio > 0) {
                document.querySelector(`nav li a[href="#${id}"]`).classList.add('activeToc');
            } else {
                document.querySelector(`nav li a[href="#${id}"]`).classList.remove('activeToc');
            }
        });
        
    },options);
        document.querySelectorAll('h2[id], h3[id]').forEach((section) => {
            observer.observe(section);
        });
}

And then add your css:

a.activeToc  { 
    font-weight: 100;
    color: red
}

arnonzooz avatar May 24 '21 07:05 arnonzooz

Thank you, @arnonzooz ๐Ÿ™‚ I didn't notice the IntersectionObserver. I think your implementation using IntersectionObserver is much simpler and nice than my current PR #506 (though I have to update the current PR). Do you think we can replace #506 by using the above code?

shuuji3 avatar May 24 '21 09:05 shuuji3

This update looks very nice!

LisaFC avatar May 24 '21 10:05 LisaFC

@shuuji3 I think you can replace the code, but I assume that's for @LisaFC to decide :)

By the way, you might not always have a side TOC. So I added a check to prevent the scrollspy from throwing an error:

if (document.querySelector(`nav li a[href="#${id}"]`) != null) {
                    document.querySelector(`nav li a[href="#${id}"]`).classList.remove('activeToc');
                }

arnonzooz avatar May 24 '21 10:05 arnonzooz

@arnonzooz pretty cool approach! I didn't even think about an IntersectionObserver to implement such a feature, even though it now seems pretty obvious ๐Ÿ˜…

Does this mean, the PR https://github.com/google/docsy/pull/506 is now obsolete?

quickstar avatar Jun 01 '21 12:06 quickstar

Hi, sorry for my slow update. I think I can update PR #506 using the above logic but it's OK to make it obsoleted and create a new PR by either me or someone else.

shuuji3 avatar Jun 01 '21 13:06 shuuji3

Here's another nice example of this...with dynamic expand/collapse of the relevant section. https://docs.coveo.com/en/346/javascript-search-framework/javascript-search-framework-components

prdsoftware avatar Jul 09 '21 02:07 prdsoftware

Hi there, I prefer the implementation in #506 to the one using IntersectionObserver. If you use IntersectionObserver the highlight is only triggered when a heading intersects with the selected box. This works OK for scrolling downwards, but when you scroll upwards the indication doesn't change back until you reach the heading at the top of the section. So for sections which are longer than a screen, the indicator shows that you are in the wrong section. This does not happen with the implementation in #506 which looks for the header at the top of the screen or the first one above the screen.

#506 is more complex, however.

MarkvanMents avatar Sep 23 '21 10:09 MarkvanMents

So sad this hasn't been implemented yet, what is holding us back?

jmichelgarcia avatar Sep 12 '22 21:09 jmichelgarcia

There's a PR in progress in #1049 that I think will meet everyone's requirements....

LisaFC avatar Sep 13 '22 10:09 LisaFC