首页 > 解决方案 > Next.js - 使用 router.push() 时禁用跳转到锚点

问题描述

使用 next 10.2,每次我们将带有哈希的 URL 推送到路由器时,next 都会跳转到锚元素。

import {useRouter} from 'next/router'

router.push('/contact#about-us');

如果我禁用也会发生这种情况scroll

router.push('/contact#about-us', undefined, { scroll: false });

我想平滑滚动到锚元素,而不是将其委托给 next.js。

import React from 'react'
import {useRouter} from 'next/router'
import PropTypes from "prop-types";

const LinkSmoothScroll = ({href, className, children}) => {
  const router = useRouter()

  const linkClicked = (e) => {
    e.preventDefault();

    router
      .push(href, undefined, {scroll: false})
      .then(() => {
        const el = document.getElementById(href);

        if ( typeof el !== "undefined" ) {
          // Since header element is fixed, and document height is not being
          // affected by fixed/absolute elements, we need to consider this
          // on the margin to be applied.
          const headerHeight = document.getElementById("nav-header")?.scrollHeight || 0;
          const scrollTopY = el.top + window.scrollY - headerHeight;

          window.scrollTo({
            left: el.left,
            top: scrollTopY,
            behavior: 'smooth'
          });
        }

      });
  }

  return (
    <a href={href} className={className} onClick={linkClicked}>{children}</a>
  )
}

LinkSmoothScroll.propTypes = {
  href: PropTypes.any,
  children: PropTypes.string,
  className: PropTypes.string
}

export default LinkSmoothScroll;

我没有找到任何方法来禁用此行为,也没有找到避免它的调整。

标签: javascriptreactjsnext.js

解决方案


几个想法。

#1 - 使用 CSS

html {
  scroll-behavior: smooth;
}

#2 - 不要在哈希中使用目标 ID

通过在哈希中为 ID 加上前缀来避免浏览器行为,这样在页面中就找不到匹配的元素(#about-us变成#prefix-about-us)。然后在导航上解析它并用JS滚动到它。

在我看来,这两种方法都不是很好,如果可能的话,最好保持默认行为不变。


推荐阅读