首先mounted中注册observer
注册快捷键略过了,简单放一下调用的函数
...
case types.ARROWUP:
this.editIndex && this.handleArrowUpDown('up');
break;
case types.ARROWDOWN:
// 如果只有一行数据向下选择是选中这个文件
(this.editIndex < length - 1 || length === 1) && this.handleArrowUpDown('down');
break;
...
handleArrowUpDown(type) {
// this.actionType = type;
// 如果只有一个文件或文件夹则选中当前文件
if (this.docInitList.length === 1) {
this.tableRowClick(this.docInitList[0]);
return;
}
if (this.editStatus) {
this.doRename(this.docInitList[this.editIndex].docName);
this.editStatus = false;
}
type === 'up' ? (this.editIndex--, this.lastClickIndex--) : (this.editIndex++, this.lastClickIndex++);
// 上下选中文件对位置进行跟踪
this.scrollFileLocation();
this.tableRowClick(this.docInitList[this.editIndex]);
},
滚动条的定位使用了scrollIntoView的api
为了获取table中每一行的dom所以获取整个table中的li 的 dom数组集合
但是离开页面他无法知道是上下键选择导致的还是滚动条滚动的所以再注册滚动条事件改一个type
data() {
rowObserver: '',
// 表格中li->dom元素集合
rowDomList: [],
// 类型为:键盘上下键或者滚动条
actionType: '',
// 上次注册的row observe dom信息
lastRow: '',
}
mounted() {
this.registerRowObserver();
},
methods: {
queryAll() {
...
// 每次重新查询整个页面会修改dom结构,所以重新获取dom节点
// 根据新的dom获取新的dom列表
this.rowDomList = Array.from(this.$refs.multipleTable.$el.getElementsByClassName('el-table__row'));
},
registerRowObserver() {
this.rowObserver = new IntersectionObserver((entries) => {
console.log('entries', entries);
console.log('ratio', entries[0].intersectionRatio);
if (!entries[0].intersectionRatio > 0) {
console.log('离开页面');
const row = this.rowDomList[this.editIndex];
// 如果为上则跳转至顶部,如果为下则跳转至底部
switch (this.actionType) {
case 'up':
row.scrollIntoView(true);
break;
case 'down':
row.scrollIntoView(false);
break;
default:
break;
}
}
});
console.log('item', this.rowObserver);
},
// 方法通过observer判断元素脱离窗口
scrollFileLocation(type) {
this.rowObserver.unobserve(this.lastRow);
const row = this.rowDomList[this.editIndex];
this.rowObserver.observe(row);
this.lastRow = row;
},
},
beforeDestroy() {
this.rowObserver.disconnect();
this.$refs.multipleTable.$el.removeEventListener('scroll', this.handleType, true);
}