自定义vxe-table表头标题文字过多,显示两行多余省略号并给出tooltip
在上一篇已经实现表头换行,本文将继续实现对含有省略号的标题做出tooltip提示。
最终效果如下图:
1、首先在body创建一个div
let tooltipDiv = document.createElement('div')
tooltipDiv.setAttribute("class","vxe-table--tooltip-wrapper")
document.body.appendChild(tooltipDiv);
2、对表头添加鼠标移入移出事件
mounted() {
let that = this
setTimeout( () => {
const tooltipDom = document.querySelector('.vxe-table--tooltip-wrapper')
let th =document.querySelectorAll('.vxe-table--header th.vxe-header--column')
let storeColumn = this.$store.state.autoFilter.columnTitleObj
for(let i=0;i<th.length;i++){
let colid = th[i].getAttribute("colid")
let currColumn = that.$refs.table.getColumnById(colid)
let isTooltip = false
let orgTitle = ''
for(let j = 0; j < storeColumn.length; j++){
if(storeColumn[j]['prop'] == currColumn['property']){
isTooltip = storeColumn[j]['tooltip']
orgTitle = storeColumn[j]['orgTitle']
break
}
}
if(isTooltip){
th[i].addEventListener('mouseenter',(e) => {
const { scrollTop, scrollLeft, visibleWidth } = this.$TOOL.getDomNode()
const { top, left } = this.$TOOL.getAbsolutePos(e.target)
const el = th[i]
const marginSize = 6
const offsetHeight = el.offsetHeight
const offsetWidth = el.offsetWidth
let tipLeft = left
//let tipTop = top - offsetHeight - marginSize
tipLeft = Math.max(marginSize, left + Math.floor((e.target.offsetWidth - offsetWidth) / 2))
if (tipLeft + offsetWidth + marginSize > scrollLeft + visibleWidth) {
tipLeft = scrollLeft + visibleWidth - offsetWidth - marginSize
}
if (top - offsetHeight < scrollTop + marginSize) {
//tipStore.placement = 'bottom'
//tipTop = top + e.target.offsetHeight + marginSize
}
let arrowLeft = `${left - tipLeft + e.target.offsetWidth / 2}px`
tooltipDom.classList.add("theme--dark","size--small","placement--top","is--enterable",
"is--visible","is--arrow","is--actived")
tooltipDom.setAttribute("style","width:auto;left:"+tipLeft+"px;top:126px;z-index:1000;")
tooltipDom.innerHTML = '<div class="vxe-table--tooltip-content">'+orgTitle+'</div><div class="vxe-table--tooltip-arrow" style="left:'+arrowLeft+'"></div>'
})
th[i].addEventListener( 'mouseleave',() => {
console.log('鼠标移出')
tooltipDom.classList.remove("placement--top","is--visible","is--actived")
})
}
}
},1500)
}
工具函数
/**
* 获取某DOM节点的信息
* @param elem {object} DOM节点
* @returns {{boundingLeft: number, visibleWidth: *, top: *, left: *, boundingTop: number, visibleHeight: *}}
*/
tool.getAbsolutePos = function(elem){
const bounding = elem.getBoundingClientRect()
const boundingTop = bounding.top
const boundingLeft = bounding.left
const { scrollTop, scrollLeft, visibleHeight, visibleWidth } = this.getDomNode()
return { boundingTop, top: scrollTop + boundingTop, boundingLeft, left: scrollLeft + boundingLeft, visibleHeight, visibleWidth }
}
/**
* 获取body DOM对象相关信息
* @returns {{visibleWidth: number, visibleHeight: number, scrollLeft: number, scrollTop: number}}
*/
tool.getDomNode = function() {
const documentElement = document.documentElement
const bodyElem = document.body
return {
scrollTop: documentElement.scrollTop || bodyElem.scrollTop,
scrollLeft: documentElement.scrollLeft || bodyElem.scrollLeft,
visibleHeight: documentElement.clientHeight || bodyElem.clientHeight,
visibleWidth: documentElement.clientWidth || bodyElem.clientWidth
}
}
在vuex加入
export default {
state: {
columnTitleObj: [], //列表头标题
orgTitle: '', //原表头标题
},
mutations:{
SET_COLUMN_TITLE(state,item){
state.columnTitleObj = item
},
SET_ORG_TITLE(state,item){
state.orgTitle = item
},
}
}
在 resizableChange 方法添加如下内容
resizableChange({column}){
let orgColumn = this.$store.state.autoFilter.columnTitleObj
for(let i = 0; i < orgColumn.length; i++){
if(orgColumn[i].prop == column.property){
this.$store.commit("SET_ORG_TITLE", orgColumn[i]['orgTitle'])
break
}
}
let orgTitle = this.$store.state.autoFilter.orgTitle
let l = orgTitle.length //column.title.length
let f = 16 //每一个字大小,实际上是每一个字的比例值,大概会比字体大小差很少大一点,
let subLen = ~~(2 * (Number(column['resizeWidth']) - 30 )) / f
let lineCount = ~~((Number(column['resizeWidth']) - 30 ) / f)
let showTextNum = 2 * lineCount
let isTooltip = false
if(l > showTextNum){
column.title = this.$TOOL.subString(orgTitle,10,true)
isTooltip = true
}else{
column.title = this.$TOOL.subString(orgTitle,subLen,false)
isTooltip = false
}
for(let i = 0; i < orgColumn.length; i++){
if(orgColumn[i].prop == column.property){
orgColumn[i].tooltip = isTooltip
break
}
}
this.$store.commit("SET_COLUMN_TITLE", orgColumn)
}