React Functional Components中的偏移顶部,getBoundingClientRect无法正常工作

时间:2019-06-24 01:43:42

标签: reactjs scroll components ref use-effect

我正在尝试在滚动屏幕期间使用React Functional组件实现类交换站点导航。

我在Windows中添加了一个侦听器,并且正在使用getBoundingClientRect方法检查我的顶部到达更改其类的位置的时刻。

以下代码始终返回Top等于零,而不管滚动位置如何。

在这个例子中我哪里出问题了?

import React, {useEffect, useRef} from "react";

const Navigation = () => {
  const inputRef = useRef();

  const sections = [{
    name: "Portfolio",
    url: "#portfolio"
  },
  {
    name: "About",
    url: "#about"
  },
  {
    name: "Contact",
    url: "#contact"
  }];

  const navLinks = sections.map((section, index) => {
    return (
      <li className="nav-item mx-0 mx-lg-1" key={index}>
        <a className="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href={section.url}>{section.name}</a>
      </li>
    )
  });

  const handleScroll = () => {
    let offsetTop  = inputRef.current.getBoundingClientRect().top;
    console.log('Top ' + offsetTop);
  };

  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
  });

  return (
    <nav className="navbar navbar-expand-lg bg-secondary text-uppercase fixed-top" id="mainNav" ref={ inputRef }>
      <div className="container">
        <a className="navbar-brand js-scroll-trigger" href="#page-top">Start Bootstrap</a>
        <button className="navbar-toggler navbar-toggler-right text-uppercase font-weight-bold bg-primary text-white rounded" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
          Menu
            <i className="fas fa-bars"></i>
        </button>
        <div className="collapse navbar-collapse" id="navbarResponsive">
          <ul className="navbar-nav ml-auto">
            {navLinks}
          </ul>
        </div>
      </div>
    </nav>
  );
};

export default Navigation;

滚动顶部,右侧,底部,左侧,高度和宽度位置时相同。

我希望滚动页面时最高值会改变。


我的代码正在运行,请遵循最终版本

import React, { useEffect, useRef, useState } from "react";
import { Link, animateScroll as scroll } from "react-scroll";

const Navigation = () => {
  const inputRef = useRef();
  const [navClass, setNavClass] = useState('');

  const sections = [{
    name: "Portfolio",
    url: "portfolio"
  },
  {
    name: "About",
    url: "about"
  },
  {
    name: "Contact",
    url: "contact"
  }];

  const navLinks = sections.map((section, index) => {
    return (
      <li className="nav-item mx-0 mx-lg-1" key={index}>
        <Link
          activeClass="active"
          to={section.url}
          spy={true}
          smooth="easeInOutQuart"
          offset={-70}
          duration={800}
          className="nav-link py-3 px-0 px-lg-3 rounded"
          href="">
          {section.name}
        </Link>
      </li>
    )
  });

  const scrollToTop = () => {
    scroll.scrollToTop();
  };

  const handleScroll = () => {
    let offsetTop = window.pageYOffset;
    if ( offsetTop > 100 ){
      setNavClass('navbar-shrink');
    }else{
      setNavClass('');
    }
  };

  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
  });

  return (
    <nav className={`navbar navbar-expand-lg bg-secondary text-uppercase fixed-top ${navClass}`} id="mainNav" ref={inputRef}>
      <div className="container">
        <a className="navbar-brand js-scroll-trigger" href="#page-top" onClick={scrollToTop}>Start Bootstrap</a>
        <button className="navbar-toggler navbar-toggler-right text-uppercase font-weight-bold bg-primary text-white rounded" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
          Menu
            <i className="fas fa-bars"></i>
        </button>
        <div className="collapse navbar-collapse" id="navbarResponsive">
          <ul className="navbar-nav ml-auto">
            {navLinks}
          </ul>
        </div>
      </div>
    </nav>
  );
};

export default Navigation;

1 个答案:

答案 0 :(得分:0)

如果您的目标是根据窗口的滚动位置更改导航栏的类别,则改用window.pageYOffset更为合理。考虑到导航栏实际上永远不会离开其位置,因此,每当您调用.getBoundingClientRect().top时,它将始终为0。

  const handleScroll = () => {
    let offsetTop  = window.pageYOffset;
    console.log('Top ' + offsetTop);
  };

查看此沙箱,了解如何更改滚动条上导航栏的外观:https://codesandbox.io/s/navbar-change-color-onscroll-jepyc