react实现锚点定位

6,440 阅读1分钟

话不多说,上效果图

实现锚点定位用到了react-scroll官网

实现过程

1、安装react-scroll

yarn add react-scroll
# 或者
npm install react-scroll

2、引入安装包

import Scroll, { scroller } from 'react-scroll';

3、实现滑动屏幕时,被选中的导航栏跟着改变

addEvents = () => {
  Events.scrollEvent.register('begin', () => {
    window.removeEventListener('scroll', this.scrollControl);
  });
  Events.scrollEvent.register('end', () => {
    window.addEventListener('scroll', this.scrollControl);
  });
  window.addEventListener('scroll', this.scrollControl);
};

scrollControl = () => {
  const { lastNavPos } = this.state;
  const { tabs } = this.props;
  const scrollTop = window.pageYOffset;
  const offsets = this.navOffsets();
  tabs && tabs.map(nav => {
    const element = document.getElementById(nav.index);
    if (!element) {
      return;
    }
    const elementRect = element.getBoundingClientRect();
    if (!elementRect) {
      return;
    }
    const elementTop = elementRect.top;
    // 向下滑动
    if ((scrollTop > lastNavPos) && (elementTop - offsets < 0) && !selectedNav.includes(nav)) {
      selectedNav.push(nav);
      const currentNav = selectedNav[selectedNav.length - 1];
      this.setState({
        currentTab: currentNav.index
      });
    } else { // 向上滑动
      if (elementTop - offsets > 0 && selectedNav.includes(nav)) {
        selectedNav.pop();
        const currentNav = selectedNav[selectedNav.length - 1];
        this.setState({
          currentTab: currentNav.index
        });
      }
    }
  });
  this.setState({
    lastNavPos: scrollTop
  });
}

// 计算导航栏和topbar的位置
navOffsets() {
  const beautyNav = document.getElementById('beautyNav');
  const beautyBar = document.getElementById('beautyBar');
  if (!beautyNav) {
    return 0;
  }
  const navComponent = beautyNav.children[0];
  if (!navComponent) {
    return 0;
  }
  const navHeight = navComponent.offsetHeight;
  if (beautyBar) {
    const barheight = beautyBar.children[0].offsetHeight;
    return barheight + navHeight;
  }
  return navHeight;
}

4、实现点击切换tab,自动定位到相应位置

changeTab(item) {
  this.setState({
    currentTab: item.index
  });
  const offset = this.navOffsets();
  scroller.scrollTo(
    item.index,
    {
      smooth: true,
      offset: -offset
    }
  );
}