What would your opinion be of a "reading position" indicator on DEV?

Ben Halpern - Aug 16 '19 - - Dev Community

We have this open PR and I'd love to hear opinions on the value of a feature like this:

Reading position indicator #1626

Is your feature request related to a problem? This is not a problem but I find nice that you have this bar that tells you the amount of scroll left until the end of the article.

Describe the solution you'd like My solution is to add a progress bar inside the #top-bar in nav and depending in the current position of the scroll it will change the percentage of this progress bar. The idea will be also that the bar color is the same as the user profile color, in my case dark green.

How to see an example? (GIF at the bottom) I created this code snippet that you can add in the Chrome Dev Tools > Sources > Snippets, and execute it with Ctrl+Enter (at least in Linux), be aware that you need to be in a post/article page for this to work.

const addProgressBarCSS = () => {
  let css = document.createElement('style');
  css.type = 'text/css';
  css.innerHTML = `
    progress::-webkit-progress-bar {
      background-color: transparent;
    }

    progress::-webkit-progress-value {
      background-color: #0D4D4B;
    }

    progress::-moz-progress-bar {
      background-color: #0D4D4B;
    }
  `;
  document.querySelector("head").appendChild(css);
}

addProgressBarCSS()

let topBar = document.querySelector("#top-bar")
let articleElement = document.querySelector("article");

let readingBarElement = document.createElement("progress");
readingBarElement.id = "reading-bar";
readingBarElement.setAttribute("style", `
    width: 100%;
    position: absolute;
    height: 5px;
    top: 49px;
    bottom: 20px;
    left: 0;
    right: 0;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: none;
    background-color: transparent;
    color: #0D4D4B;
`);
readingBarElement.setAttribute("value", pageYOffset);
readingBarElement.setAttribute("max", articleElement.getBoundingClientRect().height);

topBar.appendChild(readingBarElement);

window.addEventListener('scroll', () => {
    let currentScrollPosition = pageYOffset;
    let readingBar = document.querySelector("#reading-bar");
    let article = document.querySelector("article");
    let articlePositions = article.getBoundingClientRect();
    let start = articlePositions.y;
    let end = articlePositions.height;

    if (currentScrollPosition >= end) {
        readingBar.value = end;
    } else if (currentScrollPosition > start) {
        readingBar.value = currentScrollPosition;
    } else {
        readingBar.value = 0;
    }
});
Enter fullscreen mode Exit fullscreen mode

Screenshot andd GIF explanation Gif link

image

This is the example:

My only technical concern here would be ensuring it doesn't add jankiness to the scrolling behavior, but otherwise this is more of a UX discussion.

Feel free to weigh in.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .