Scroll to Top/bottom

A set of floating buttons on the screen that quickly scroll to the top and bottom of the page, and scroll up/down one page.

Per 21-02-2025. 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 of Violentmonkey.

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==
// @name         Scroll to Top/bottom
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  A set of floating buttons on the screen that quickly scroll to the top and bottom of the page, and scroll up/down one page.
// @author       Kamiya Minoru
// @match        *://*/*
// @exclude      *://www.google.com/*
// @exclude      *://www.google.com.tw/*
// @exclude      *://www.google.co.jp/*
// @exclude      https://www.bilibili.com/
// @exclude      https://*.microsoft/*
// @exclude      https://gemini.google.com/*
// @exclude      https://chatgpt.com/
// @exclude      https://claude.ai/*
// @exclude      https://www.perplexity.ai/*
// @exclude      https://chat.deepseek.com/*
// @exclude      https://www.twitch.tv/
// @noframes
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Create a Trusted Types policy
    const escapeHTMLPolicy = trustedTypes.createPolicy('myEscapePolicy', {
        createHTML: (string) => string
    });

    // Create a container for the buttons
    var container = document.createElement('div');
    container.style.position = 'fixed';
    container.style.right = '10px';
    container.style.top = '185px';
    container.style.transform = 'translateY(-50%)';
    container.style.zIndex = '9999999';
    document.body.appendChild(container);

    // Function to create a button
    function createButton(innerHTML, onClick, tooltip) {
        var button = document.createElement('div');
        button.innerHTML = escapeHTMLPolicy.createHTML(innerHTML); // 使用 TrustedHTML
        button.style.width = '30px';
        button.style.height = '30px';
        button.style.cursor = 'pointer';
        button.style.backgroundColor = 'transparent';
        button.style.color = 'grey';
        button.style.textAlign = 'center';
        button.style.fontSize = '24px';
        button.style.borderRadius = '50%';
        button.style.userSelect = 'none';
        button.style.marginBottom = '8px';
        button.style.opacity = '0.4';
        button.style.transition = 'all 0.3s';
        button.style.display = 'flex';
        button.style.alignItems = 'center';
        button.style.justifyContent = 'center';
        button.style.border = '1px solid grey';
        button.title = tooltip;
        button.addEventListener('click', onClick);
        button.addEventListener('mouseover', function() {
            button.style.opacity = '1';
            button.style.filter = 'drop-shadow(0 0 1px grey)';
            button.style.color = '#FFF';
            if (tooltip === 'Close') {
                button.style.backgroundColor = 'red';
            }
        });
        button.addEventListener('mouseout', function() {
            button.style.opacity = '0.4';
            button.style.filter = 'drop-shadow(0 0 0 grey)';
            button.style.color = 'grey';
            if (tooltip === 'Close') {
                button.style.backgroundColor = 'transparent';
            }
        });
        return button;
    }

    // Create the buttons
    var topButton = createButton('⮝', function() {
        window.scrollTo({ top: 0, behavior: 'instant' });
    }, "Scroll to Top");
    var pageUpButton = createButton('↑', function() {
        window.scrollBy({ top: -window.innerHeight, behavior: 'instant' });
    }, "Page Up");
    var pageDownButton = createButton('↓', function() {
        window.scrollBy({ top: window.innerHeight, behavior: 'instant' });
    }, "Page Down");
    var bottomButton = createButton('⮟', function() {
        window.scrollTo({ top: document.body.scrollHeight, behavior: 'instant' });
    }, "Scroll to Bottom");
    var closeButton = createButton('╳', function() {
        container.style.display = 'none';
    }, "Close");

    // Create the drag button
    var dragButton = createButton('⇅', function() {}, "drag to Move");
    dragButton.style.cursor = 'grab';

    dragButton.addEventListener('mousedown', function(e) {
        dragButton.style.cursor = 'grabbing';
        var initialX = e.clientX;
        var initialY = e.clientY;
        var initialLeft = container.offsetLeft;
        var initialTop = container.offsetTop;

        function moveAt(pageX, pageY) {
            container.style.left = initialLeft + (pageX - initialX) + 'px';
            container.style.top = initialTop + (pageY - initialY) + 'px';
        }

        function onMouseMove(event) {
            moveAt(event.clientX, event.clientY);
        }

        document.addEventListener('mousemove', onMouseMove);

        document.addEventListener('mouseup', function() {
            dragButton.style.cursor = 'grab';
            document.removeEventListener('mousemove', onMouseMove);
            document.removeEventListener('mouseup', arguments.callee);
        });
    });

    dragButton.ondragstart = function() {
        return false;
    };

    // Append buttons to the container
    container.appendChild(topButton);
    container.appendChild(pageUpButton);
    container.appendChild(pageDownButton);
    container.appendChild(bottomButton);
    container.appendChild(closeButton);
    container.appendChild(dragButton);
})();