不同页面跳转到指定位置和同页面跳到指定位置

593 阅读2分钟

一、场景

当一个页面跳转到另一个页面,有时候需要跳转到另一个页面的指定的内容部分,该内容部分有可能就是在顶部、中间、底部。还有就是很多博客网站都有目录,点击目录中的标题就能跳转到该标题的指定位置,这两种场景是该怎么实现呢?

二、实现方法

主要是用到了 scrollIntoView ,这个是dom元素才有的方法。当该元素调用scrollIntoView方法后,页面就会自动滑到该dom的位置,前提是父元素要有滚动条,滑到的位置是相对于父元素的。

简单的介绍一下语法:

element.scrollIntoView() 等同于 element.scrollIntoView(true)
true的话会滑到该元素顶部可视区域顶部对齐,
为false的话会滑到该元素底部可视区域的底部对齐
详细的语法介绍,请看 MDN 的讲解。

示例

下面用到的例子都是用react去完成的。

展示同级页面的跳转到指定位置

function App() {
  const dom = useRef<HTMLDivElement>(null);

  const listData = ['#00a1ff', 'green', 'black', 'red', 'pink','#ffd500','#ff8800','#12886b','#9b0e7c']
 
  // 点击跳转到指定位置
  const jumpTo = (index:number)=>{
    const dom = document.querySelector(`#item_${index}`)
    dom.scrollIntoView()
  }

  return (
    <div className='container'>
      <ul>
        {listData.map((item, index) => {
          // 定义id,方便选中dom元素
          return <li key={item} id={`item_${index}`} className='listItem' style={{ backgroundColor: item }}>第{index + 1}部分</li>
        })}
      </ul>
      <ul className='optionsBox'>
        {listData.map((item, index) => {
          return <li key={item} className='option_item' onClick={()=>jumpTo(index)}>跳转到第{index + 1}部分</li>
        })}
      </ul>
    </div>
  )
}

运行效果如下: 0.png 点击跳转到第四部分的效果:

1.png

不同页面之间的跳转指定位置

从一个页面跳转到另一个页面的实现本质上也是使用 scrollIntoView 方法,但是获取dom元素的方法就有所不同了,从一个页面跳转到另一个页面首先要知道跳转到哪个dom元素的位置,这就需要页面传参了,本章采用的是hash值传参的方法。
就是第一个页面跳转到第二个页面带上hash参数,如:baidu.com#two 只需要获取到 #后面的参数,然后去获取对应的dom元素再进行跳转。这时候就可以使用location.hash去获取到参数。例如:

// 假设地址为 https://baidu.com/api#test
console.log(location.hash.split('#')[1])  // test

例子:

import React, { useState, useEffect, useRef } from "react";
import { BrowserRouter, Route, Routes,useLocation,useNavigate } from 'react-router-dom'
import "./App.css";

const listData = ['#00a1ff', 'green', 'black', 'red', 'pink', '#ffd500', '#ff8800', '#12886b', '#9b0e7c']

// 开始页面
function StartPage() {
  const navigate = useNavigate()
  // 跳转到第二个页面,传值
  const jumpTo = (index) => {
    navigate(`/endPage/#${index}`)
  }
  return (
    <div  className='container'>
      <ul className='optionsBox'>
        {listData.map((item, index) => {
          return <li key={item} className='option_item' onClick={() => jumpTo(index)}>跳转到第{index + 1}部分</li>
        })}
      </ul>
    </div>
  )
}

// 跳转到的页面
function EndPage() {
  const dom = useRef<HTMLDivElement>(null);
  useEffect(() => {
    // 获取到hash的参数
    const hashProps = location.hash.split('#')[1];
    // 找到对应的指定的dom元素
    const dom = document.querySelector(`#item_${hashProps}`)
    dom.scrollIntoView()
  }, [])

  return (
    <div  className='container'>
      <ul>
        {listData.map((item, index) => {
          return <li key={item} id={`item_${index}`} className='listItem' style={{ backgroundColor: item }}>第{index + 1}部分</li>
        })}
      </ul>
    </div>
  )
}


function App() {
  return (
    <div className='container'>
      <BrowserRouter>
        <Routes>
          <Route path='/startPage'  element={<StartPage/>} />
          <Route path='/endPage' element={<EndPage/>} />
        </Routes>
      </BrowserRouter>
    </div>
  )
}

行效果如下:
第一个页面的内容

2.png 点击“跳转到第5部分” 去跳转到第二个页面

3.png