本次优化:
1.解决当一个页面存在多个表格,文本提示框出现错位现象
2.解决新增Dom节点无法正常删除,导致页面出现多个节点
问题描述: 要求el-tabel表格头部和表内容的文字,当文字超出表格宽度是隐藏并显示省略号,并且鼠标浮上去时以文字提示框的形式显示
难点:1.表格表体部分可以通过element-ui中自带的属性:show-overflow-tooltip 解决,但无法解决表头问题
难点2:表头可以用render-header函数逐一设置,但表格数量太多,页面太多,不太显示,写起来费时费力,过度重复的工作是写代码的大忌
解决思路:
1.通过全局设置js函数(方便全局去调用)
2.创建一个需要显示文本提示框的Dom节点
3.讲Dom节点显示在对应的所需要显示的表头位置
4.将Dom节点针对body定位,获取表头元素的横纵坐标(相对于窗口),用于确定定位的位置坐标
5.设置事件(onmouseover)事件和(onmouseout)鼠标移出事件,鼠标进入显示,鼠标移出隐藏
6.将函数挂在到Vue上
Vue.prototype
函数名
代码部分:
MyTooltips.js
exports.MyTooltip = function(h = 0) {
const elTooltip = document.createElement('div')
const div = document.createElement('div')
elTooltip.style.position = 'absolute'
elTooltip.style.width = '120px'
elTooltip.style.fontSize = '12px'
div.style.borderRadius = '5px'
elTooltip.style.left = '81px'
elTooltip.style.zIndex = '9999'
elTooltip.className = 'toolTipSire'
div.className = 'bubbleTail'
// 创建显示元素
let sapns
// 获取表头标签
const htmls = document.querySelectorAll('table > thead > tr')
// 获取表格元素 如果页面中有两个表格请用下标来区分 默认拿第一个表格
const selectWrap = document.querySelectorAll('.el-table__body-wrapper')[h]
// 滚动距离
let rollLeft = 0
// 循环遍历所有节点
for (let i = 0; i < htmls.length; i++) {
for (const a in htmls[i].children) {
sapns = htmls[i].children[a]
// 添加类似hover事件
if (sapns.children) {
if (sapns.children[0] !== undefined) {
sapns.children[0].onmouseover = function(event) {
rollLeft = selectWrap.scrollLeft
const lefts = getLeft(this)
const tops = getTop(this)
// 判断字体是否省略隐藏
if (this.scrollWidth > this.offsetWidth) {
elTooltip.style.left = (lefts - 40 - rollLeft) + 'px'
elTooltip.style.top = (tops - 50) + 'px'
// 获取选中元素的文字
div.innerText = event.target.innerText
div.style.backgroundColor = '#1f2f3d'
div.style.color = '#fff'
div.style.visibility = 'visible'
}
}
// 鼠标移除事件
sapns.children[0].onmouseout = function() {
div.style.visibility = 'hidden'
}
}
}
}
}
// 添加提示文本框
document.querySelector('body').appendChild(elTooltip)
elTooltip.appendChild(div)
// 清除多余的文本框元素
const rubbishNode = document.querySelectorAll('.toolTipSire')
if (rubbishNode.length > 1) {
document.body.removeChild(document.querySelector('.toolTipSire'))
}
}
// 获取元素的纵坐标(相对于窗口)
function getTop(e) {
var offset = e.offsetTop
if (e.offsetParent != null) offset += getTop(e.offsetParent)
return offset
}
// 获取元素的横坐标(相对于窗口)
function getLeft(e) {
var offset = e.offsetLeft
if (e.offsetParent != null) offset += getLeft(e.offsetParent)
return offset
}
MyTooltips.css
.bubbleTail {
visibility: hidden;
text-align: center;
padding: 5px 0;
border-radius: 6px;
/* 定位 */
position: absolute;
z-index: 1;
border-radius: 5px;
width: 120px;
height: 30px;
background-color: rgb(31, 47, 61);
color: rgb(255, 255, 255);
line-height: 22px;
}
.bubbleTail::after {
content: " ";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: black transparent transparent transparent;
}
main.js
import { MyTooltip } from './MyTooltips'
Vue.prototype.headShow = function(h) {
MyTooltip(h)
}
页面引用
//如果页面中存在一个表格无需传参直接调用
this.$nextTick(() => {
this.headShow()
})
//如果页面中存在多个表格在切换表格时需要传参
this.$nextTick(() => {
this.headShow(1)
})