滚动条及顶部底部按钮

在任何网页顶部显示滚动进度条,并提供滚动到顶部和底部的按钮,优化性能,减少卡顿现象。

目前为 2024-10-06 提交的版本。查看 最新版本

// ==UserScript==
// @name         滚动条及顶部底部按钮
// @namespace    https://gf.qytechs.cn/
// @version      1.1
// @description  在任何网页顶部显示滚动进度条,并提供滚动到顶部和底部的按钮,优化性能,减少卡顿现象。
// @author       Leo
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 缓存DOM元素
    const progressBar = document.createElement('div');
    const bar = document.createElement('div');
    const scrollBtns = document.createElement("div");

    // 初始化样式
    const initStyles = () => {
        progressBar.id = 'progress';
        progressBar.style.pointerEvents = 'none';
        document.body.insertBefore(progressBar, document.body.firstChild);

        bar.className = 'bar';
        Object.assign(bar.style, {
            position: 'fixed',
            zIndex: '999999999',
            top: '0',
            left: '0',
            width: '0%',
            height: '2px',
            background: 'linear-gradient(90deg, #03a9f4, #f441a5)',
            boxShadow: '0 0 40px #03a9f4, 0 0 50px #f441a5, 0 0 60px #03a9f4',
            borderRadius: '0.5em',
            transition: 'width 0.2s ease'
        });
        progressBar.appendChild(bar);

        scrollBtns.className = "goto_top_end";
        Object.assign(scrollBtns.style, {
            position: "fixed",
            bottom: "10px",
            right: "5rem",
            zIndex: "1000000000",
            display: "flex",
            flexDirection: "row",
            alignItems: "center"
        });
        document.body.appendChild(scrollBtns);
    };

    // 获取页面滚动信息
    const getScrollInfo = () => ({
        scrollTop: window.pageYOffset || document.documentElement.scrollTop,
        pageHeight: Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
        clientHeight: window.innerHeight || document.documentElement.clientHeight
    });

    // 更新进度条
    const updateProgress = () => {
        const { scrollTop, pageHeight, clientHeight } = getScrollInfo();
        const maxScroll = pageHeight - clientHeight;
        const progress = maxScroll > 0 ? (scrollTop / maxScroll) * 100 : 0;
        const newWidth = `${Math.min(progress, 100)}%`;
        if (bar.style.width !== newWidth) {
            bar.style.width = newWidth;
        }
    };

    // 创建滚动按钮
    const createScrollButton = (text, onClick) => {
        const button = document.createElement("button");
        button.innerText = text;
        Object.assign(button.style, {
            padding: '10px',
            marginLeft: '10px',
            cursor: 'pointer',
            backgroundColor: '#0005',
            color: '#eee',
            border: 'none',
            borderRadius: '5px',
            fontSize: '16px'
        });
        button.onclick = onClick;
        return button;
    };

    // 创建滚动到顶部和底部的按钮
    const createScrollButtons = () => {
        const fragment = document.createDocumentFragment();
        const toTop = createScrollButton("⬆️顶部", () => {
            window.scrollTo({ top: 0, behavior: "smooth" });
        });

        const toEnd = createScrollButton("⬇️底部", () => {
            const { clientHeight, pageHeight } = getScrollInfo();
            window.scrollTo({ top: pageHeight - clientHeight, behavior: "smooth" });
        });

        fragment.appendChild(toTop);
        fragment.appendChild(toEnd);
        scrollBtns.appendChild(fragment);
    };

    // 页面加载时初始化
    const init = () => {
        initStyles();
        updateProgress();
        createScrollButtons();
    };

    window.addEventListener('load', init, { once: true });

    // 监听滚动事件,使用 requestAnimationFrame 和 passive
    const onScroll = () => {
        requestAnimationFrame(updateProgress);
    };

    window.addEventListener('scroll', onScroll, { passive: true });

    // 移除事件监听器
    const cleanup = () => {
        window.removeEventListener('scroll', onScroll);
    };

    window.addEventListener('beforeunload', cleanup, { once: true });

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址