惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
GbyAI
GbyAI
爱范儿
爱范儿
H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Check Point Blog
M
MIT News - Artificial intelligence
量子位
宝玉的分享
宝玉的分享
MongoDB | Blog
MongoDB | Blog
V
Visual Studio Blog
罗磊的独立博客
F
Fortinet All Blogs
美团技术团队
博客园_首页
博客园 - 【当耐特】
L
LangChain Blog
月光博客
月光博客
腾讯CDC
The Cloudflare Blog
D
Docker
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

Hyde Blog

Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog
Hyde Blog
Hyde · 2026-05-19 · via Hyde Blog

astro

<!-- 顶部滚动条组件 --> 
---
---

<div id="scroll-progress-bar" class="scroll-progress-bar"></div>

<script is:inline>
(function () {
    let progressBar = null;
    let cachedScrollHeight = 0;
    let cachedClientHeight = 0;

    const throttle = function(func, delay) {
        let timeoutId;
        let lastExecTime = 0;

        return function() {
            const currentTime = Date.now();

            if (currentTime - lastExecTime > delay) {
                func.apply(this, arguments);
                lastExecTime = currentTime;
            } else {
                clearTimeout(timeoutId);
                timeoutId = setTimeout(function() {
                    func.apply(this, arguments);
                    lastExecTime = Date.now();
                }, delay - (currentTime - lastExecTime));
            }
        };
    };

    function handleScroll() {
        requestAnimationFrame(function() {
            if (!progressBar) {
                progressBar = document.getElementById('scroll-progress-bar');
                if (!progressBar) return;
            }

            if (cachedScrollHeight === 0 || cachedClientHeight === 0) {
                cachedScrollHeight = document.documentElement.scrollHeight;
                cachedClientHeight = document.documentElement.clientHeight;
            }

            const totalHeight = cachedScrollHeight - cachedClientHeight;
            const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
            const progress = totalHeight > 0 ? (scrollTop / totalHeight) * 100 : 0;

            if (progressBar) {
                progressBar.style.width = progress + '%';
            }
        });
    }

    function handleResize() {
        cachedScrollHeight = 0;
        cachedClientHeight = 0;
    }

    const throttledHandleScroll = throttle(handleScroll, 50);

    function init() {
        // Initial calculation
        handleScroll();

        // Add scroll listener
        window.addEventListener('scroll', throttledHandleScroll, { passive: true });

        // Add resize listener
        window.addEventListener('resize', handleResize, { passive: true });
    }

    // Ensure DOM is fully loaded before initialization
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();
</script>

<style>
    .scroll-progress-bar {
        position: fixed;
        top: 0;
        left: 0;
        height: 2px;
        width: 0;
        background: linear-gradient(
            107deg,
            rgb(255, 182, 133) -30.6%,
            rgb(255, 111, 29) -1.11%,
            rgb(252, 181, 232) 39.14%,
            rgb(135, 148, 255) 73.35%,
            rgb(60, 112, 255) 97.07%,
            rgb(60, 112, 255) 118.97%
        );
        z-index: 9999;
        pointer-events: none;
    }
</style>

astro

---
import ScrollProgressBar from "@components/features/ScrollProgressBar.astro";
---

<body
    <div id="progress-bar"></div>
    <ScrollProgressBar />
</body>