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

一、场景

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

二、实现方法

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

简单的介绍一下语法:

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

示例

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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参数,如:https://baidu.com#two,只需要获取到 #后面的参数,然后去获取对应的dom元素再进行跳转。这时候就可以使用location.hash去获取到参数。例如:

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

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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