一、 前言
这篇文章就主要来讲一下大屏滚动的几种方案,当然,如果大家有其他方案,欢迎在评论区点拨一下小弟,废话不多说,直接进入正题
二、方案集合
2.1、利用色差
利用色差效果给用户一个“滚屏”的体验,使用这种方案的前提是斑马色要有足够的色差感,这里使用antd 的table为例,效果如下:
核心思想如下:
- 定时切换数据
- 在颜色上,
每页或者每屏的颜色一定要互相取反
核心代码如下:
import { useState, useEffect } from 'react';
import { Table } from 'antd';
const data1 = [...];
const data2 = [...];
const data3 = [...];
function App (){
const [dataSource, setDataSource] = useState(data1);
const [column, setColumn] = useState([...]);
const [count, setCount] = useState(1);
const setTableRowClass = (record, index) => {
if (record.key % 2 !== 0){
return count % 2 !== 0 ? 'one-color' : 'two-color';
} else {
return count % 2 !== 0 ? 'two-color' : 'one-color';
}
}
const changeTableData = (count) => {
setDataSource(count === 2 ? data2 : data3);
}
useEffect(()=>{
let timer = setInterval(() => {
count++;
setCount(count);
changeTableData(count);
}, 6000);
return () => {
clearInterval(timer);
}
});
return <Table column = {column} dataSource = {dataSource} rowClassName = {setTableRowClass}/>
}
2.2、整页翻页效果
通过批量操作高度来达到“翻页”效果,效果如下:
核心思想如下:
- 定时“补充”数据
- 记录上一页数据行的范围,并将这个范围内的所有数据行的高度都置为0
核心代码如下:
import React from 'react';
import { Table } from 'antd';
const data1 = [...];
const data2 = [...];
const data3 = [...];
const columns = [...];
class App extends React.Component {
constructor(props){
super(props);
this.state = {
data: data1
}
this.count = 1;
}
newFixedTimeChangeData = (timeout, count) => {
// 定时补充数据
this.setState(state => {
return {
data: state.data.concat(count === 2 ? data2 : data3)
}
}, () => {
if (document.querySelector('.antd-table-row-item')){
let arr = Array.from(document.querySelectorAll('.antd-table-row-item'));
// 记录上一页数据行的范围,并将这个范围内的所有数据行的高度都置为0
for (let index = (count - 1) * 5 - 5; index < (count - 1) * 5; index++){
arr[index].classList.add('new-height-antd');
}
}
})
}
componentDidMount(){
this.timerInterval = setInterval(() => {
this.count = this.count + 1;
this.newFixedTimeChangeData(5000, this.count);
}, 5000);
}
render (){
return <Table column = { column } dataSource = { this.state.data } />
}
}
2.3、单行翻页效果
与整页翻页效果不同的是,单行翻页效果每次只将一行数据的高度置为0,效果如下:
核心代码如下:
// 其余代码与整页翻滚的代码一样
// animationIndex:记录应该执行翻页效果的数据行的位置
let animationIndex = 0;
newFixedTimeChangeData = (timeout, count) => {
// 定时补充数据
this.setState(state => {
return {
data: state.data.concat(count === 2 ? data2 : data3)
}
}, () => {
if (document.querySelector('.antd-table-row-item')){
let arr = Array.from(document.querySelectorAll('.antd-table-row-item'));
arr[animationIndex].classList.add('new-height-antd');
animationIndex++;
}
})
}
2.4、整页滚动效果
这个也是一个常见的效果,效果如下:
核心思路:
- 动态的改变每个tr的transform。
核心代码(react):
import React from 'react';
import { Table } from 'antd';
const column = [...];
const dataSource = [...];
class App extends React.Component {
constructor(props){
super(props);
this.state = {
dataSource,
scrollTop: 0
}
}
setTableCssScroll = () => {
this.setState((state) => {
return {
...state,
// 每次执行,都向上滚动10px
scrollTop: state.scrollTop - 10
}
}, () => {
if (document.querySelector('.antd-table-row-item')){
let arr = Array.from(document.querySelectorAll('.antd-table-row-item'));
for (let index = 0; index < arr.length; index++){
// 没行都向上10px
arr[index].style.transform = `translateY(${this.state.scrollTop}px)`
}
}
});
}
componentDidMount(){
this.timerInterval = setInterval(() => {
this.setTableCssScroll();
}, 3000);
}
render (){
return <Table column = { column } dataSource = { dataSource }>
}
}
核心代码(css)
// 否则向上transform 的tr会与表头重合
.ant-table-thead th {
z-index: 999;
}
三、实际项目中还应该思考的点
大家其实会发现,上面的方案中,所有的数据都是模拟的,根本没有与后端进行交互。所以我认为,在实际项目中,我们至少还应该考虑以下几点:
- 如果数据到了最后一屏 or 数据总量小于一屏,是否还需要执行滚动效果?
- 数据如果过多,应该要保证dom节点数量固定,防止浏览器崩溃。(这里给大家一个思路,data正常维护,但是删除dom一定要原生删除)
- 数据请求的时机。(以整页翻滚为例,每页翻滚前都要请求一遍数据,防止前一页与下一页之间出现空隙)
四、最后
好啦,又到了结尾了,如果大家还有什么好的方案并且这篇文章里没有讲到的,欢迎大家补充。还有第三点里要思考的点里,我并没有给出相应的代码(我虽然在项目里解决了上述的问题,但是我认为并不是最优解,所以没有在文章里体现),如果大家有好的方法,也欢迎评论区里补充。