Scroll Page Progress

Visual indicator of page progress while scrolling

Per 06-08-2024. Zie de nieuwste versie.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @license MIT
// @name         Scroll Page Progress
// @namespace    http://tampermonkey.net/
// @version      2024-08-05
// @description  Visual indicator of page progress while scrolling
// @author       You
// @match        *://*/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function debounce(callback, wait) {
        let timerId;
        return (...args) => {
            clearTimeout(timerId);
            timerId = setTimeout(() => {
                callback(...args);
            }, wait);
        };
    }

    const observer = new MutationObserver(function (mutations) {
        const attributesMutated = mutations.filter(mutation => mutation.type === 'attributes')
        const nonStyleAttributes = attributesMutated.filter(mutation => mutation.attributeName !== 'style')
        nonStyleAttributes.forEach(attribute => percentageIndicatorContainer.removeAttribute(attribute.attributeName))
    });

    const body = document.body;
    const percentageIndicator = document.createElement('div');
    const percentageIndicatorContainer = document.createElement('div');

    Object.assign(percentageIndicatorContainer.style, {
        position: 'fixed',
        top: '10px',
        right: '10px',
        borderRadius: '50%',
        border: '3px solid white',
        color: 'white',
        fontWeight: 'bold',
        overflow: 'hidden',
        fontSize: '13px',
        backgroundImage: 'linear-gradient(to right, #434343 0%, black 100%)',
        boxShadow: `0 1px 1px hsl(0deg 0% 0% / 0.075),
        0 2px 2px hsl(0deg 0% 0% / 0.075),
        0 4px 4px hsl(0deg 0% 0% / 0.075),
        0 8px 8px hsl(0deg 0% 0% / 0.075),
        0 16px 16px hsl(0deg 0% 0% / 0.075)`,
        zIndex: 9999999999
    })

    percentageIndicatorContainer.classList.add('scroll-progress-extension')




    const percentageText = document.createTextNode('-%');
    percentageIndicator.style.width = '3em'
    percentageIndicator.style.height = '3em'
    percentageIndicator.style.display = 'flex'
    percentageIndicator.style.justifyContent = 'center'
    percentageIndicator.style.alignItems = 'center'

    function getCurrentScrollProgress() {
        const winScroll = document.body.scrollTop || document.documentElement.scrollTop;
        const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
        const progress = (winScroll / height) * 100;
        return Math.trunc(progress);
    }

    percentageIndicatorContainer.appendChild(percentageIndicator);
    percentageIndicator.appendChild(percentageText);
    body.appendChild(percentageIndicatorContainer);

    document.addEventListener('scroll', debounce(() => {
        percentageText.textContent = getCurrentScrollProgress() + '%'
    }, 100))


    observer.observe(percentageIndicatorContainer,{ attributes: true, childList: true, characterData: true })
})();