来看效果
html
使用elementUI的Popover 弹出框和input组件
<el-popover placement="bottom-end" trigger="hover">
<el-input v-model="positionStep" type="text" placeholder="可输入步骤后按回车快速定位" @change="positionTaskStep" />
<el-table :data="taskStepTip" max-height="400" ref="stepInfoTable">
<el-table-column width="400" label="步骤:">
<template slot-scope="scope">
{{scope.row.no}}. {{scope.row.text}}
</template>
</el-table-column>
</el-table>
<div slot="reference" class="task-step-help"><i class="el-icon-question"></i> 任务步骤</div>
</el-popover>
关键:
- @change: 仅在输入框失去焦点或用户按下回车时触发事件
- 设置一个ref方便获取dom元素
功能
滚动定位
- 滚动定位我们可以使用scrollTop
Element.scrollTop 属性可以获取或设置一个元素的内容垂直滚动的像素数。
更多属性信息可查看:https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollTop - 滚动到指定行
可以先获取到tr的高度, 然后再根据输入的步骤去计算高度(行号*高度),
最后可通过vue的$el获取dom对象设置scrollTop值
ps: - 我这步骤是从1开始, 所以要将输入的行号-1
- 另外要注意在this.$nextTick函数内操作dom, 避免获取不到dom元素
const trHeight = 48; //一行固定的高度
let inputStep = this.positionStep; //输入的值
let stepInfoTable = this.$refs.stepInfoTable.$el.querySelector('.el-table__body-wrapper'); //步骤信息列表的dom元素
stepInfoTable.scrollTop = trHeight * (inputStep - 1); //滚动定位
注意:
- 如果获取的scrollTop始终为0(赋值scrollTop不成功), 可以使用以下函数检查滚动所在的盒子获取是否正确
window.addEventListener(
'scroll',
() => {
var box = _this.$refs.stepInfoTable.$el.querySelector('.el-table__body-wrapper');
// console.log(scrollTop.scrollHeight)
console.log(box, box.scrollTop); // 查看打印的值是否有变化 如果有 则说明滚滚动条在这个标签中
// scrollTop.scrollTop = scrollTop.scrollHeight // 可以尝试下 滚动滚动条。一直在底部则可以设置成功
},
true
);
字体闪烁
主要是用了过渡效果+timeout延迟还原
- 先获取到具体的行
- 设置要高亮的样式
- 高亮样式设置过渡时间(transition)
- 使用timeout还原样式
let currTr = stepInfoTable.querySelector('tbody').children[inputStep - 1]; //获取定位的tr
//设置闪烁样式
currTr.style.color = '#07c160';
currTr.style.fontSize = '15px';
currTr.style.transition = '1s';
setTimeout(() => {
currTr.style.color = '#606266';
currTr.style.fontSize = '14px';
}, 1500);
搜索过滤
- 对输入内容做匹配过滤, 用display控制过滤结果
//如果输入的不是纯数字,则对内容进行模糊匹配
var regExp = new RegExp(`(${inputStep})`, 'i');// 模糊匹配的正则表达式
if (!/^[0-9]*$/.test(inputStep)) {
for (let index = 0; index < this.taskStepTip.length; index++) {
let tr = stepInfoTable.querySelector('tbody').children[index]; //当前遍历的tr
if (regExp.test(this.taskStepTip[index].text)) {
tr.style.display = 'table-row';
} else {
tr.style.display = 'none';
}
}
}
注意
当改变table内容的时候, 这个max-height会动态变化, 重置时要把这个maxHeight根据页面处理一下, 不然内容会显示不全
用@input事件监测输入内容为空时, 恢复所有项的显示
//输入内容为空
if (!this.positionStep) {
let stepInfoTable = this.$refs.stepInfoTable.$el.querySelector('.el-table__body-wrapper'); //步骤信息列表的dom元素
stepInfoTable.style.maxHeight = '350px';
let trList = stepInfoTable.querySelector('tbody').children; //所有tr
for (let index = 0; index < trList.length; index++) {
trList[index].style.display = 'table-row';
}
}