如何用Svelte实现向上滚动时显示div菜单?代码失效求排查
问题分析与修复方案
主要错误点
- oldY未更新:初始化
oldY = newY[1]时,newY是空数组,所以oldY一开始是undefined,且后续updateY函数只往数组添加元素,从未更新oldY的值,导致判断条件永远无法生效。 - 事件参数错误:
updateY的参数写了y,但svelte:window的scroll事件回调接收的是事件对象,不是scrollY值,这里会覆盖全局的y变量,造成逻辑混乱。 - 判断逻辑颠倒:向上滚动时,
scrollY是减小的(比如从100滚到50),应该是oldY > y时显示菜单,而非oldY < y。 - 数组处理冗余:用数组存储5个Y值完全没必要,只需要记录上一次的滚动位置即可,冗余逻辑反而增加复杂度。
修复后的代码
<script> let y; let oldY = 0; // 初始化上一次滚动位置为0 function updateY() { oldY = y; // 每次滚动后更新上一次的位置 } </script> <svelte:window bind:scrollY={y} on:scroll={updateY} /> {#if oldY > y} <div>... 菜单内容 ...</div> {/if}
优化说明
- 移除冗余的
newY数组,直接用oldY记录上一次滚动位置,逻辑更简洁。 - 修正事件回调参数问题,通过
bind:scrollY={y}已获取滚动位置,updateY直接使用全局变量y即可。 - 将判断条件改为
oldY > y,匹配向上滚动(当前位置小于之前位置)时显示菜单的需求。 - 初始化
oldY为0,避免初始状态下的undefined导致判断失效。
如果需要避免滚动时频繁触发更新,可以添加防抖处理:
<script> let y; let oldY = 0; let timeoutId; function updateY() { clearTimeout(timeoutId); timeoutId = setTimeout(() => { oldY = y; }, 100); // 100ms防抖,减少触发频率 } </script> <svelte:window bind:scrollY={y} on:scroll={updateY} /> {#if oldY > y} <div>... 菜单内容 ...</div> {/if}
内容的提问来源于stack exchange,提问作者SoulTech9
相关产品推荐
相关产品推荐

