一、table自动滚动优化
1、优化原理:
function scrollTable(){
let table = document.getElementById('table');
let tableHeight = parseInt(window.getComputedStyle(table).height); // 获取table高度
let rows = table.getElementsByTagName('tr');
let firstRowHeight = parseInt(window.getComputedStyle(rows[0]).height); // 获取行高
let rowIndex = parseInt(table.scrollTop / firstRowHeight); // 获取当前滚动到第几行
let visibleRowCount = parseInt(tableHeight / firstRowHeight); // 获取可见的行数
let lastRowIndex = parseInt((tableHeight + table.scrollTop) / firstRowHeight); // 获取最后一行的索引
let requiredRowCount = visibleRowCount * 2; // 设置缓存的最小行数
let currentRowCount = rows.length; // 当前行数
let bufferRowCount = requiredRowCount - currentRowCount;
if(bufferRowCount > 0) {
for(let i = 0; i < bufferRowCount; i++){
let newRow = createNewRow(); // 创建一行
table.appendChild(newRow); // 插入新行
}
}
else if(lastRowIndex >= currentRowCount - 1) {
// 加载更多数据
}
}
2、优化内容:
使用虚拟滚动技术将很多行文本直接放到Web页面上, 而只在用户需要滚动时才显示他们。这样可以更好地处理大量数据,而不会影响渲染性能。
3、实现方法:
将table设置为一个div的子元素,并设置固定高度和滚动条,而不是将所有行直接添加到table中。
4、代码示例:
<div style="height: 300px;overflow: auto;">
<table>
<tbody id="tableBody" style="height: 100%;"></tbody>
</table>
</div>
二、vue table滚动
1、实现原理:
使用vue的组件化思想,对table进行封装并提供滚动功能。
2、代码示例:
<template>
<div class="scrollable-table" ref="tableWrapper">
<table>
<thead>
<tr>
<th v-for="heading in headings">{{ heading }}</th>
</tr>
</thead>
<tfoot>
<tr v-if="fetching"><td colspan="{{ headings.length }}">Loading...</td></tr>
</tfoot>
<tbody>
<tr v-for="row in rows">
<td v-for="key in Object.keys(row)">{{ row[key] }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
name: 'ScrollableTable',
props: {
rows: Array,
headings: Array,
fetchMoreRows: Function
},
data () {
return {
fetching: false
}
},
mounted () {
this.$refs.tableWrapper.addEventListener('scroll', this.handleScroll)
},
beforeDestroy () {
this.$refs.tableWrapper.removeEventListener('scroll', this.handleScroll)
},
methods: {
handleScroll (event) {
const tableBody = this.$refs.tableWrapper.querySelector('table tbody')
const distance = tableBody.getBoundingClientRect().bottom - this.$refs.tableWrapper.getBoundingClientRect().bottom
if (distance < 10 && !this.fetching) {
this.fetching = true
this.fetchMoreRows().then((newRows) => {
this.fetching = false
if (newRows) {
this.rows.push(...newRows)
}
})
}
}
}
}
</script>
三、antd table自动滚动
1、实现原理:
借助antd的组件库,使用虚拟滚动优化,提供table滚动功能。
2、代码示例:
<Table
columns={columns}
dataSource={data}
scroll={{ y: 240 }}
/>
四、table横向滚动
1、实现原理:
对于table过宽的情况,可以使用CSS样式中的overflow-x属性和white-space属性来进行水平滚动。
2、代码示例:
table {
width: 800px;
overflow-x: scroll;
white-space: nowrap;
}
五、listbox自动滚动
1、实现原理:
在ListBox control 下,当用户选择某个值时,可以将listbox选项自动滚动到选中项的位置。
2、代码示例:
function selectItem (itemIndex) {
const listItem = document.getElementById(`list-item-${itemIndex}`)
const list = document.getElementById('list')
const listHeight = list.offsetHeight
const itemHeight = listItem.offsetHeight
const itemPosition = listItem.offsetTop
const currentScrollTop = list.scrollTop
const scrollTop = itemPosition - (listHeight - itemHeight) / 2
list.scrollTop = scrollTop
}
六、el table滚动加载
1、实现原理:
使用Vue的Element UI组件库中的el-table,可以用虚拟滚动优化,并且提供滚动加载数据的功能。
2、代码示例:
<el-table
:data="tableData"
:row-height="40"
height="320"
style="width: 100%"
ref="table"
@scroll="scrollHandler"
:highlight-current-row="false"
>
<el-table-column
prop="name"
label="Name"
width="180"
/>
<el-table-column
prop="address"
label="Address"
width="360"
/>
</el-table>
七、layui table滚动加载
1、实现原理:
使用LayUI中的table控件,可以根据滚动条的位置动态加载数据,实现滚动加载。
2、代码示例:
var tableIns = table.render({
elem: '#demo',
url: '/demo/table/user/',
page: true,
cols: [[
{field:'id', title:'ID', width:80},
{field:'username', title:'用户名', width:120},
{field:'email', title:'邮箱', width:150},
{field:'sign', title:'签名', width:200},
{field:'sex', title:'性别', width:80},
{field:'city', title:'城市', width:100},
{field:'experience', title:'积分', width:80},
{field:'ip', title:'IP', width:120},
{field:'logins', title:'登入次数', width:100},
{field:'joinTime', title:'加入时间', width:120}
]],
done: function(res, curr, count) {
console.log('done');
if (res.code !== 0) {
layer.msg(res.msg);
return;
}
if (res.count === 0) {
$(".layui-table-main").empty();
}
}
});
$(document).ready(function(argument) {
$('.layui-table-view').scroll(function () {
console.log('scroll');
var scrollTop = this.scrollTop;
var scrollHeight = $("table").height();
var windowHeight = $(this).height();
if (scrollTop + windowHeight == scrollHeight) {
table.reload('demo', { // 指定表格唯一标识符
page: {
curr: tableIns.config.page.curr + 1
}
});
}
});
});
八、table滚动显示
1、实现原理:
对于table列数量较多的情况,可以使用CSS样式中的overflow-y属性和fixed-layout属性来进行固定列滚动。
2、代码示例:
table {
overflow-y: scroll;
display: block;
table-layout: fixed;
}
td {
width: 300px;
}
九、table虚拟滚动选取
1、实现原理:
使用虚拟滚动技术将很多行文本直接放到Web页面上, 而只在用户需要滚动时才显示他们。这样可以更好地处理大量数据,而不会影响渲染性能。
2、代码示例:
function scrollTable(){
let table = document.getElementById('table');
let rowHeight = parseInt(window.getComputedStyle(rows[0]).height); // 获取行高
let rowIndex = parseInt(table.scrollTop / rowHeight); // 获取当前滚动到第几行
let visibleRowCount = parseInt(table.offsetHeight / rowHeight); // 获取可见的行数
let lastRowIndex = parseInt((table.offsetHeight + table.scrollTop) / rowHeight); // 获取最后一行的索引
let requiredRowCount = visibleRowCount * 2; // 设置缓存的最小行数
let currentRowCount = rows.length; // 当前行数
let bufferRowCount = requiredRowCount - currentRowCount;
if(bufferRowCount > 0) {
for(let i = 0; i < bufferRowCount; i++){
let newRow = createNewRow(); // 创建一行
table.appendChild(newRow); // 插入新行
}
}
else if(lastRowIndex >= currentRowCount - 1) {
// 查找选中行
for(let i = rowIndex; i < lastRowIndex; i++) {
if(rows[i].classList.contains('selected')){
rows[i].classList.remove('selected');
}
}
}
// 批量选取行
rows.slice(rowIndex, lastRowIndex).forEach((row) => {
row.classList.add('selected');
});
}