Javascript 点击焦点侧导航的链接打开向下滚动的页面

Javascript 点击焦点侧导航的链接打开向下滚动的页面,javascript,reactjs,scrollto,Javascript,Reactjs,Scrollto,我继承了一个react/node/prismic应用程序,它有一个ScrollToTop.js文件,以确保页面在顶部加载,当从主导航菜单访问时,页面会这样做 这个应用程序还有一个小的侧导航,在你向下滚动之前是隐藏的(用tabIndex控制) 错误:当您单击侧导航的链接时,无论您在打开侧导航时滚动了多远,结果页面都会出现。相反,我希望这些从顶部开始 我们有一个Layout.js文件用于总体布局,还有一个特定的SideNav.js用于小side nav。我是react/javascript新手,我还

我继承了一个react/node/prismic应用程序,它有一个ScrollToTop.js文件,以确保页面在顶部加载,当从主导航菜单访问时,页面会这样做

这个应用程序还有一个小的侧导航,在你向下滚动之前是隐藏的(用tabIndex控制)

错误:当您单击侧导航的链接时,无论您在打开侧导航时滚动了多远,结果页面都会出现。相反,我希望这些从顶部开始

我们有一个Layout.js文件用于总体布局,还有一个特定的SideNav.js用于小side nav。我是react/javascript新手,我还不知道如何(a)将ScrollToTop逻辑应用于这些sidenav链接,或者(b)添加一个额外的
窗口。对于这种特殊情况,scrollTo(0,0)
。有人能推荐如何/在何处更新吗

SideNav.js:

import React from 'react'
import CTAButton from './CTAButton'
import { Link } from 'react-router-dom'
import { Link as PrismicLink } from 'prismic-reactjs'
import PrismicConfig from '../../../prismic-configuration'
import PropTypes from 'prop-types'
import * as PrismicTypes from '../Utils/Types'

const matchPaths = {
  'about': 'About us',
  'projects': 'Projects',
  'news': 'News'
}

class SideNav extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      expanded: false
    }
    this.handleKey = this.handleKey.bind(this)
    this.expandMenu = this.expandMenu.bind(this)
    this.keypressed = undefined
    this.main = undefined
    this.bug = undefined
    this.toggle = false
    this.windowTop = 0
  }

  checkMobile() {
    if (window.innerWidth <= 800) {
      this.setState({scrollThreshold: 50})
    }
  }

  componentDidMount() {
    this.checkMobile()
    this.keypressed = this.handleKey
    window.addEventListener('keydown', this.keypressed)
    this.main = document.getElementsByClassName('top-nav-logo')[0]
    this.bug = document.getElementsByClassName('side-nav-bug-wrap')[0]

  }

  componentWillUnMount() {
    window.removeEventListener('keydown', this.keypressed)
  }

  handleKey(e) {
    if (e.keyCode === 27 && this.state.expanded) {
      this.expandMenu()
    }
  }

  expandMenu() {
    const el = document.scrollingElement || document.documentElement
    if (!this.state.expanded) {
      this.windowTop = el.scrollTop
    } else {
      el.scrollTop = this.windowTop
    }

    this.setState({
      expanded: !this.state.expanded
    })
    document.body.classList.toggle('nav-lock')
  }

  render() {
    const expanded = this.state.expanded ? 'expanded' : 'contracted'
    const tabIndex = this.state.expanded ? '1' : '-1'

    if (this.state.scrollThreshold === 50 && this.state.expanded) {
      this.props.removeListener()
      this.main.setAttribute('style', 'display:none')
      this.bug.setAttribute('style', 'display:none; position:absolute')
    }
    else if (this.state.scrollThreshold === 50 && !this.state.expanded) {
      this.props.addListener()
      this.main.setAttribute('style', 'display:inline')
      this.bug.setAttribute('style', 'display:flex; position:fixed')
    }

    const menu = this.props.menu.map((menuItem, index) => {
      const menuLink = PrismicLink.url(menuItem.link, PrismicConfig.linkResolver)
      const label = menuItem.label[0].text
      let marker
      if (typeof this.props.location !== 'undefined') {
        // Match label to window location to move indicator dot
        marker = label === matchPaths[this.props.location] ? this.props.location : 'inactive'
      }
      return (
        <li key={index} className="side-nav-li">
          <Link to={label} className="side-nav-link" onClick={this.expandMenu} tabIndex={tabIndex}>{label}</Link>
             <div className={`side-nav-marker ${marker}`}/>
        </li>
      )
    })

    return (
      <div className='side-nav-wrapper'>
        <Link to='/' className={`side-nav-logo-main ${this.props.visibility}`} alt=""/>
        <div className={`side-nav-bug-wrap ${this.props.visibility}`} onClick={this.expandMenu}>
          <div className='side-nav-bug-icon' />
        </div>
        <div className={`side-nav ${expanded}`}>
            <div className={'side-nav-menu-wrap'}>
              <div className="side-nav-control-wrap">
                <Link to="/" className="side-nav-logo" alt="Count Me In logo" onClick={this.expandMenu} tabIndex={tabIndex}/>
                <button className="side-nav-exit" onClick={this.expandMenu} tabIndex={tabIndex}/>
              </div>
              <nav>
                <ul className="side-nav-menu-items">
                  { menu }
                  <CTAButton />
                </ul>
              </nav>
            </div>
          </div>
        <div className={`side-nav-overlay ${expanded}`} onClick={this.expandMenu}/>
      </div>
    )
  }
}


SideNav.propTypes = {
  removeListener: PropTypes.func,
  addListener: PropTypes.func,
  location: PropTypes.string,
  visibility: PropTypes.string,
  menu: PropTypes.arrayOf(PropTypes.shape({
      label: PrismicTypes.PrismicTextTypes,
      link: PropTypes.shape({
          id: PropTypes.string,
          isBroken: PropTypes.bool,
          lang: PropTypes.string,
          link_type: PropTypes.string,
          slug: PropTypes.string,
          tags: PropTypes.array,
          type: PropTypes.string,
          uid: PropTypes.string
      })
  }))
}

export default SideNav
router.js:

import React from 'react'
import { Route, Switch } from 'react-router-dom'
import ScrollToTop from './app/Utils/ScrollToTop'
import routes from './routes'

export default (({prismicCtx, PRISMIC_UNIVERSAL_DATA}) => {
  return (
    <ScrollToTop>
      <Switch>
        {routes(prismicCtx, PRISMIC_UNIVERSAL_DATA).map((route, index) => {
          const copyRoute = Object.assign({}, route)
          if (copyRoute.render) delete copyRoute.component
          return <Route key={`route-${index}`} {...copyRoute} />
        })}
      </Switch>
    </ScrollToTop>
  )
})
从“React”导入React
从“react router dom”导入{Route,Switch}
从“./app/Utils/ScrollToTop”导入ScrollToTop
从“/routes”导入路由
导出默认值({prismicCtx,PRISMIC_UNIVERSAL_DATA})=>{
返回(
{路由(prismicCtx,PRISMIC_UNIVERSAL_DATA).map((路由,索引)=>{
const copyRoute=Object.assign({},route)
如果(copyRoute.render)删除copyRoute.component
返回
})}
)
})

查看不同的react生命周期步骤,我为componentWillUpdate(在ScrollToTop.js中)添加了相同的scrollTo行为,这些页面再次从此菜单顶部加载

    componentWillUpdate() {
    window.scrollTo(0, 0)
}

我猜ScrollToTop既不更新也不获取
位置
。另外,我认为
location
将是一个对象,因此您需要比较
location.pathname
这是一个字符串。但是你需要在路由器上使用
看看这篇文章,或者感谢@Vl4dimyr!是的,这是另一个问题:这个分支用于更新一系列软件包版本,随着这些更新,我们开始得到“您不应该在外部使用或使用Router()。我删除了“withRouter”,我想看看我是否能以其他方式实现这一点……我认为
Route
的直接子组件或通过
Route
显示的组件将自动注入
location
只需注销提供给
Route
的组件中的道具,这可能会起作用。
import React from 'react'
import { Route, Switch } from 'react-router-dom'
import ScrollToTop from './app/Utils/ScrollToTop'
import routes from './routes'

export default (({prismicCtx, PRISMIC_UNIVERSAL_DATA}) => {
  return (
    <ScrollToTop>
      <Switch>
        {routes(prismicCtx, PRISMIC_UNIVERSAL_DATA).map((route, index) => {
          const copyRoute = Object.assign({}, route)
          if (copyRoute.render) delete copyRoute.component
          return <Route key={`route-${index}`} {...copyRoute} />
        })}
      </Switch>
    </ScrollToTop>
  )
})
    componentWillUpdate() {
    window.scrollTo(0, 0)
}