Svelte中实现滚动条条件隐藏的方案咨询
解决Svelte中自定义滚动条非滚动时隐藏的问题
核心思路
- 通过监听页面滚动事件维护滚动状态变量,用定时器延迟切换状态,避免滚动过程中频繁闪烁
- 利用Svelte的
<svelte:body>类绑定功能,动态控制滚动条的显示/隐藏,避免直接修改全局样式引发冲突 - 将滚动条样式与状态类绑定,默认隐藏,仅在滚动时激活显示,完全不影响背景动画逻辑
修改后的完整代码
<script> import { onMount, onDestroy } from "svelte"; import { fade } from "svelte/transition"; import Header from "../components/header.svelte" import CenterBlock from "../components/centerBlock.svelte"; import { linear } from "svelte/easing"; let animate = false; let isScrolling = false; let scrollTimer; let shapes = [ { top: 50, left: 50, deltaX: -1, deltaY: 1 }, { top: 350, left: 1000, deltaX: -1, deltaY: 1 }, { top: 200, left: 500, deltaX: -1, deltaY: 1 }, { top: 650, left: 1100, deltaX: -1, deltaY: 1 }, ]; function updateShapes() { shapes = shapes.map(shape => { let newTop = shape.top + shape.deltaY; let newLeft = shape.left + shape.deltaX; let shapeRadius = 300; if (newTop <= 0 || newTop >= window.innerHeight - shapeRadius) { shape.deltaY = -shape.deltaY; } if (newLeft <= 0 || newLeft >= window.innerWidth - shapeRadius) { shape.deltaX = -shape.deltaX; } return { top: shape.top + shape.deltaY, left: shape.left + shape.deltaX, deltaX: shape.deltaX, deltaY: shape.deltaY, }; }); requestAnimationFrame(updateShapes); } // 滚动事件处理逻辑 function handleScroll() { isScrolling = true; clearTimeout(scrollTimer); // 停止滚动1.2秒后隐藏滚动条 scrollTimer = setTimeout(() => { isScrolling = false; }, 1200); } onMount(() => { updateShapes(); animate = true; window.addEventListener('scroll', handleScroll); isScrolling = false; }); onDestroy(() => { window.removeEventListener('scroll', handleScroll); clearTimeout(scrollTimer); }); </script> <!-- 动态给body绑定滚动可见类 --> <svelte:body class:scroll-visible={isScrolling} /> {#if animate} <div transition:fade={{delay: 250, duration: 1000, easing: linear}}> <Header/> </div> <div id="background" transition:fade={{delay:500, duration:5000, easing: linear}}> {#each shapes as shape (shape)} <div class="shape" style={`top: ${shape.top}px; left: ${shape.left}px;`}></div> {/each} </div> <CenterBlock/> <div style="height: 200vh;"></div> {/if} <style> @import '../css/gambetta.css'; :global(body) { margin: 0; background-color: #151813; /* 默认隐藏滚动条(兼容多浏览器) */ scrollbar-width: none; /* Firefox */ -ms-overflow-style: none; /* IE/Edge */ } /* 滚动时显示滚动条的类 */ :global(body.scroll-visible) { scrollbar-width: thin; /* Firefox */ -ms-overflow-style: auto; /* IE/Edge */ } /* Webkit内核滚动条样式 - 仅在滚动状态下生效 */ :global(body.scroll-visible::-webkit-scrollbar) { width: 10px; } :global(body.scroll-visible::-webkit-scrollbar-track) { background: #151813; border-radius: 5px; } :global(body.scroll-visible::-webkit-scrollbar-thumb) { background: #730d23; border-radius: 10px; } :global(body.scroll-visible::-webkit-scrollbar-thumb:hover) { background: #400a15; } #background { position: fixed; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: -1; } .shape { position: absolute; width: 300px; height: 300px; opacity: 0.5; background: radial-gradient(circle, #730d23 40%, transparent 75%); filter: blur(30px); } </style>
关键修改说明
- 滚动状态控制:新增
isScrolling变量和定时器逻辑,滚动时激活状态,停止滚动后延迟隐藏,避免频繁切换 - Svelte规范操作:用
<svelte:body>替代直接修改:global(body),更符合Svelte组件化开发规范,避免全局样式冲突 - 样式隔离:将滚动条样式绑定到
scroll-visible类,默认状态下完全隐藏滚动条,仅在滚动时加载样式,不干扰背景动画 - 跨浏览器兼容:添加Firefox、IE/Edge的滚动条适配代码,确保全平台效果一致
- 内存泄漏预防:在组件销毁时移除滚动监听和定时器,避免残留事件占用资源
内容的提问来源于stack exchange,提问作者LeMecWeird
相关产品推荐
相关产品推荐

