使用
scrollIntoView
实现元素内子元素的平滑滚动,
下面是模拟接口list返回,然后通过按钮切换下一个,页面就会滚动到响应的位置
具体scrollIntoView
有一些其他参数来配置滚动的具体交换,网上去查即可
备注:下面的代码使用Vite框架 + React Hooks + 简单的TS
,实现的方案都是一样,具体的代码可能不同
实现效果如下:
首先第一步,配置电脑设置
如图所示:打开【控制面板】- 搜索【性能】 - 调整 Windows 的外观和性能选项 - 开启【窗口内的动画控件和元素】
第二步,写页面和样式代码
这里使用了react + ts,不管用什么语言框架,理解其中思路,代码实现可能不同
// tsx 文件
import { useEffect, useRef, useState } from 'react'
import './index.css'
export default function Index() {
const listRef = useRef<any>() // 需要滚动的父容器
const [acitve, setActive ] = useState(0) //当前激活项
const [list, setList] = useState<any>([])
// 生命周期获取接口
useEffect(() => {
getData()
}, [])
// 监听active激活位置的变化,滚动到相应为止
useEffect(() => {
let childEl = listRef.current.childNodes[acitve]
// 由于接口是异步的,一开始进入页面会执行要处理初始情况,list有值了才开始
if(list.length){
childEl.scrollIntoView({ behavior: 'smooth' });
}
}, [acitve])
// 这里模仿接口来的数据
const getData = async () => {
let res = await new Promise(resolve => {
setTimeout(() => {
return resolve([0,1,2,3,4,5,6,7,8,9])
}, 500)
})
setList(res)
}
// 设置当前激活项目
const onChange = () => {
setActive(pre => {
let next = pre >= 9 ? 0: pre+1
return next
})
}
return (
<div className='page'>
<div className='head'>
<span>acitve: {acitve}</span>
<button onClick={onChange}>next</button>
</div>
<div className='list_warp'>
<div className='list' ref={listRef}>
{ list.map((item:number) =>
<div key={item} className='card'>{item}</div>
)}
</div>
</div>
</div>
)
}
对应的 index.css
/* 同目录下的index.css */
.page{
margin: 24px;
width: 300px;
}
.list_warp{
margin: 24px 0;
width: 300px;
height: 60vh;
padding: 12px;
border: 2px solid red;
background: pink;
box-sizing: border-box;
}
.list{
height: 100%;
overflow-y: scroll;
scrollbar-width: none;
-ms-overflow-style: none;
&::-webkit-scrollbar{
display: none;
}
}
.head{
display: flex;
justify-content: space-between;
}
.card{
overflow: hidden;
background: greenyellow;
margin-bottom: 12px;
height: 200px;
border: 1px solid green;
box-sizing: border-box;
}
到这里就是实现了效果了