【问题标题】:How to detect scroll direction when content changes height on scroll当内容在滚动时改变高度时如何检测滚动方向
【发布时间】:2021-03-23 15:44:05
【问题描述】:

在以静态尺寸滚动页面时检测滚动方向非常简单。但是,如果其中一个元素是粘性标题并在滚动时更改高度,它会保持更改pageYOffset 并进入无限循环上下跳跃。

Example sandbox 如果你滚动到它开始收缩的地方,它就会开始跳跃。

我想出的一些可能的解决方案是添加一个垫片,以在粘性导航变小时进行补偿。但这需要在实际组件中进行。想知道是否有办法只在 useScrollDirection 钩子中使用 js。

我尝试过的另一件事是使用 document.documentElement.scrollHeight 并检查大小变化,但这也没有帮助。

【问题讨论】:

    标签: javascript css reactjs user-interface animation


    【解决方案1】:

    只是一个建议。我认为你没有充分利用position: sticky。您不需要事件侦听器来实现您想要的行为。您可以完全使用 CSS 来完成此操作,并让浏览器为您处理一切。

    .app {
      font-family: sans-serif;
      text-align: center;
      height: 300vh;
    }
    
    .nav {
      position: sticky;
      top: -120px;
      height: 150px;
      background: aquamarine
    }
    
    .nav_item {
       position: sticky;
        top: 0px;
        margin: 0;
    }
    <div class="app">
      <h1>Hello CodeSandbox</h1>
      <nav class="nav">
        <p class="nav_item">Hello</p>
      </nav>
      <h2>Start editing to see some magic happen!</h2>
    </div>

    【讨论】:

    • 感谢@slumbergeist!我可能会尝试利用这个!但这个例子相当简化为真实应用程序的本质。在真正的应用程序中,字体高度和其他一些事情发生了变化,这需要滚动发出信号。
    • 你的解决方案绝对很棒,只是我不想用粘性子导航重写每个实现?
    • 我已经通过字体更改更新了示例。
    【解决方案2】:

    我遇到了同样的问题,一位同事建议我收听wheel 事件。所以我实现了以下反应钩子:

    const useLastMouseWheelDirection = () => {
      const [lastMouseWheelDirection, setLastMouseWheelDirection] = useState(
        undefined
      )
    
      useEffect(() => {
        const handler = (event) => {
          setLastMouseWheelDirection(event.deltaY >= 0 ? 'down' : 'up')
        }
        window.addEventListener('wheel', handler)
        return () => window.removeEventListener('wheel', handler)
      }, [])
    
      return lastMouseWheelDirection
    }
    

    这个解决方案有一些严重的局限性:

    • 显然触摸事件被忽略
    • 单击并拖动滚动条不会触发事件

    对于所需行为的另一个副作用是它不会考虑元素是否甚至溢出,尽管可以扩展钩子以捕获这种情况。

    更多MDN Web Docs状态:

    注意:不要将滚轮事件与滚动事件混淆。 Wheel 事件的默认操作是特定于实现的,并且不一定调度滚动事件。即使是这样,wheel 事件中的 delta* 值也不一定反映内容的滚动方向。因此,不要依赖 wheel 事件的 delta* 属性来获取滚动方向。而是在滚动事件中检测目标的scrollLeft和scrollTop的值变化。

    所以请对这个答案持保留态度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-04
      • 2022-01-26
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多