React 监听页面滚动

const scrollEvent = event => {
 if (!event.srcElement.scrollTop) {
    //处理向上使劲滚动的时候scrollTop为undefined
    return undefined
  }
  // 滚动的高度
  const scrollTop =
    (event.srcElement ? event.srcElement.scrollTop : false) ||
    window.pageYOffset ||
    (event.srcElement ? event.srcElement.body.scrollTop : 0)
  // 视窗高度
  const clientHeight = (event.srcElement && event.srcElement.clientHeight) || document.body.clientHeight
  // 页面高度
  const scrollHeight = (event.srcElement && event.srcElement.scrollHeight) || document.body.scrollHeight
  // 距离页面底部的高度
  const height = scrollHeight - scrollTop - clientHeight

  return height
}

const initialState = {
  page: 1,
  pageSize: 50
}

const reducer = (state, action) => {
  const payload = reap(action, 'payload', {})
  switch (action.type) {
    case 'update':
      return { ...state, ...payload }
    default:
      throw new Error()
  }
}

function Demo(props) {
  const {
    getList
  } = props

  const [hasMore, setHasMore] = useState(true)
  const [state, dispatch] = useReducer(reducer, initialState)
  const [list, setList] = useState([])

  const _handleScroll = useCallback(
    event => {
      const height = scrollEvent(event)

      if (hasMore && height <= 100) {
        const page = state.page + 1
        //get new list data
        dispatch({
          type: 'update',
          payload: {
            page
          }
        })
      }
    },
    [hasMore, state.page]
  )

  useEffect(() => {
    const scrollDom = document.getElementById('layoutContentContainer')
    scrollDom.addEventListener('scroll', _handleScroll)

    return () => scrollDom.removeEventListener('scroll', _handleScroll)
  }, [_handleScroll])

  useEffect(() => {
    const { page, pageSize, searchText } = state
    getList({ page, pageSize, name: searchText }).then(res => {
      const code = reap(res, 'code', 0)
      if (code === 200) {
            //判断设置还有没有数据可以加载了  setHasMore()
           //设置获取的数据列表setList(a => a.concat(list))
      }
    })
  }, [getList, state])

  return (
    <React.Fragment>
        {/** show list map to ui */}
    </React.Fragment>
  )
}
Demo.propTypes = {
  getList: PropTypes.func
}

export default Demo

scrollEvent函数在是计算滚动条距离距离底部的高。
挂载scroll事件监听触发计算当滚动条距离底部小于等于100时进行再次数据加载

React 应用中,为了在路由切换后返回页面时恢复之前的滚动位置,你可以使用浏览器提供的 `scrollBehavior` 和 `window.history.replaceState()` 方法结合状态管理工具如 React Router 或 Redux。 首先,在浏览器支持的情况下(例如现代浏览器),可以在配置 `scrollBehavior` 函数时指定滚动行为。这个函数接收三个参数:`top`, `left`, 和 `options`。你通常会返回一个对象,其中包含 `behavior` 字段,设置为 `'auto'`、`'scroll'` 或 `'smooth'`,表示默认滚动、跟随链接滚动还是平滑滚动。 ```javascript // 在服务端渲染时,如果需要保存滚动位置 if (typeof window !== 'undefined') { window.addEventListener('popstate', function () { const scrollPosition = JSON.parse(sessionStorage.getItem('scrollPosition')); if (scrollPosition) { window.scrollTo(scrollPosition.top, scrollPosition.left); } }); } // 当路由改变并希望保存滚动位置 router.push('/new-route', '/new-route', { scroll: true }); // 在组件中,你可以将滚动位置存储在本地存储或Redux store中 componentDidUpdate(prevProps) { if (prevProps.location.key !== this.props.location.key && typeof window !== 'undefined') { sessionStorage.setItem('scrollPosition', JSON.stringify({ top: window.scrollY, left: window.scrollX })); } } ``` 当从 `/old-route` 跳转到 `/new-route` 并设置了 `{ scroll: true }` 的时候,跳转后会自动保存当前滚动位置,然后在用户点击浏览器回退按钮返回 `/old-route` 时,通过监听 `popstate` 事件恢复滚动位置。 请注意,这种方法依赖于用户的浏览器历史记录和状态存储,不是所有场景都适用,比如SPA应用的初始加载或刷新页面时,滚动位置无法恢复。此外,对于非常复杂的滚动动画,可能还需要额外的手动处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值