React实战:返回顶部

实现返回顶部效果

  • 滚动一定高度后从下到上平移出现
  • 点击后自动滚动到顶部
  • 滚动到顶部以后从上到下平移消失

image-20220423183411202

实现逻辑

  • 监听滚动,发现滚动距离大于阈值(目前设为视窗高度),则显示按钮,否则隐藏
    • 判断条件:document.documentElement.scrollTop>document.documentElement.clientHeight
    • useState:用一个布尔值isVisible来表示当前元素显示或隐藏
  • 控制按钮显示,监听isVisible,有两种方法
    • 没有动画效果:返回的虚拟DOM里内联地写 style={{display: isVisible? "block":"none"}}
    • 有平移效果:ref.current.style.bottom=`${bottomBias+20}px` 搭配 transition: bottom 1s;
  • 点击按钮,回到顶部
    • document.body.scrollTop = document.documentElement.scrollTop = 0;

代码

api

  • bottomBias:距离底部的额外距离,适用于底部有导航栏的页面(导航栏高度是50),没有导航栏可以不传
1
<BackToTop bottomBias={50}></BackToTop>

实现

js

index.jsx

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
60
61
import React, { useEffect, useRef, useState } from "react";
import {jsThrottle} from "../../utils/throttle";
import './style.less'

const BackToTop=({bottomBias=0})=>{
const [isVisible, setIsVisible]=useState(false)

const ref=useRef()
function onClickHandle(){
document.body.scrollTop = document.documentElement.scrollTop = 0;
}

// 挂载:绑定滚动
useEffect(()=>{
let timer=null
const scrollHandle=()=>{
// console.log(document.documentElement.scrollTop)
if(document.documentElement.scrollTop>document.documentElement.clientHeight){
// show
setIsVisible(true)
} else {
// hide
setIsVisible(false)
}
}
// 节流
window.addEventListener("scroll", jsThrottle(scrollHandle, 1000))

return ()=>{
console.log("clear");
window.removeEventListener("scroll", scrollHandle)
}
},[])

// 监听isVisible,改变按钮的bottom
useEffect(()=>{
if (isVisible){
console.log("show")
ref.current.style.bottom=`${bottomBias+20}px`
} else {
console.log("hide")
ref.current.style.bottom=`-40px`
}
},[isVisible])


return (
// <div
// onClick={onClickHandle}
// className="back2top-container" style={{bottom: `${20+bottomBias}px`, display: isVisible? "block":"none"}}>
// <i className="iconfont icon-arrowup"></i>
// </div>
<div ref={ref}
onClick={onClickHandle}
className="back2top-container">
<i className="iconfont icon-arrowup"></i>
</div>
)
}

export default BackToTop

throttle

带强制执行的节流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export function jsThrottle(fn, delay=300){
let timer=null
function fnThrottle(...args) {
// console.log(timer)
if (!timer){
timer=setTimeout(()=>{
// console.log("throttle fn")
fn(...args)
timer=null
},delay)

}
}
return fnThrottle
}

css

style.less

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.back2top-container{
position: fixed;
right: 20px;
bottom: -40px;
height: 40px;
width: 40px;
border-radius: 50%;
border: 1px solid #ccc;
text-align: center;
line-height: 40px;
background-color: rgba(255, 255, 255, 0.9);
// 实现平移效果
transition: bottom 1s;

i{
color: blueviolet;
font-size: 24px;
}
}

iconfont

需要额外下载一个上箭头的icon,不用icon直接用文字也行
这里使用 iconfont图标库

------ 本文结束 ❤ 感谢你的阅读 ------
------ 版权信息 ------

本文标题:React实战:返回顶部

文章作者:Lury

发布时间:2022年04月23日 - 18:59

最后更新:2022年04月23日 - 19:24

原始链接:https://luryzhu.github.io/2022/04/23/exercise/BackTpTop/

许可协议:署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。