首先清楚windows文件管理的逻辑
- 按 ↓ 键选择文件,如果文件已经离开窗口那么滚动条向下准确滚动
- 按 ↑ 键选择文件则滚动条准确向上滚动
当然以上的条件是文件在可视窗口内移动
- 如果用户操作滚动条使文件脱离可视窗口内,则重新定位, 重新定位有两个规则:
{
a. 如果文件在可视窗口上方,则定位过去后文件在可视窗口的一个元素
b. 如果文件在可视窗口的下方, 则定位过去后文件在可视窗口为最后一个元素
}
我上面提到了准确二字,所以我们先把上下键的默认事件去掉, 不然他会自己控制进度条
if (e.keyCode === 38 || e.keyCode === 40) {
e.preventDefault();
}
然后开始进行下面定位的操作
HTML: 首选注册ref对于el-table
<el-table
id="multipleTable"
ref="multipleTable"
:data="docInitList"
tooltip-effect="dark"
style="width: 100%"
@select="handleSelectDoc"
@row-dblclick="getDblClickId"
@row-contextmenu="rightEvent"
@selection-change="selectChangeFn"
@row-click="tableRowClick"
:cell-style="rowClass"
:height="tableHeight"
row-key='id'
@sort-change="table
...
绑定快捷键的事件我就略过了哈, 除非有人问我再加进来
代码中的this.editIndex指的是当前文件的下标
然后开始写逻辑了:
scrollFileLocation() {
// 整个table的高度
const { tableHeight } = this;
// table表格的头高度
const tableHeader = 53;
const tableBodyHeight = tableHeight - tableHeader;
// 每个table中元素的高度
const itemHeight = 64;
this.$nextTick(() => {
// 当前滚动条已经滚动的高度
let scrolled = this.$refs.multipleTable.bodyWrapper.scrollTop;
// 获取当前窗口第一个元素的下标
const start = Math.round(scrolled / itemHeight);
// 一个窗口可以展示的数据数量
const showNum = tableBodyHeight / itemHeight;
// 获取当前窗口最后一个元素的下标
const end = Math.round(start + showNum) - 1;
// 为了文件完整显示的偏移量
let offSet = 0;
// 如果滚动条移动的很远再按上下键会重新定位
if (start - this.editIndex > 1) {
this.$refs.multipleTable.bodyWrapper.scrollTop = this.editIndex * itemHeight;
return;
}
if (this.editIndex - end > 1) {
this.$refs.multipleTable.bodyWrapper.scrollTop = (this.editIndex - showNum + 1) * itemHeight;
return;
}
// 如果上下选择文件大于窗口则移动滚动条
if (this.editIndex < start) {
offSet = scrolled % itemHeight;
scrolled -= itemHeight + offSet;
} else if (this.editIndex > end) {
offSet = (scrolled + itemHeight * showNum) % itemHeight;
scrolled += itemHeight - offSet;
} else {
return;
}
this.$refs.multipleTable.bodyWrapper.scrollTop = scrolled;
});
},