element-plus如何实现内容超出时显示浮层
前言
同事接到需求:在 el-table-header
中实现 el-table-column
的 show-overflow-tooltip 功能。
于是问到: “element是怎么判断出:长的显示,短的不显示的?”
源码
通过查看 element-plus源码 可以看到:
ts
const handleCellMouseEnter = (
event: MouseEvent,
row: T,
tooltipEffect: string
) => {
const table = parent
const cell = getCell(event)
const namespace = table?.vnode.el?.dataset.prefix
if (cell) {
const column = getColumnByCell(
{
columns: props.store.states.columns.value,
},
cell,
namespace
)
const hoverState = (table.hoverState = { cell, column, row })
table?.emit(
'cell-mouse-enter',
hoverState.row,
hoverState.column,
hoverState.cell,
event
)
}
// 判断是否text-overflow, 如果是就显示tooltip
const cellChild = (event.target as HTMLElement).querySelector(
'.cell'
) as HTMLElement
if (
!(
hasClass(cellChild, `${namespace}-tooltip`) &&
cellChild.childNodes.length
)
) {
return
}
// use range width instead of scrollWidth to determine whether the text is overflowing
// to address a potential FireFox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1074543#c3
const range = document.createRange()
range.setStart(cellChild, 0)
range.setEnd(cellChild, cellChild.childNodes.length)
const rangeWidth = range.getBoundingClientRect().width
const padding =
(Number.parseInt(getStyle(cellChild, 'paddingLeft'), 10) || 0) +
(Number.parseInt(getStyle(cellChild, 'paddingRight'), 10) || 0)
if (
rangeWidth + padding > cellChild.offsetWidth ||
cellChild.scrollWidth > cellChild.offsetWidth
) {
createTablePopper(
parent?.refs.tableWrapper,
cell,
cell.innerText || cell.textContent,
{
placement: 'top',
strategy: 'fixed',
},
tooltipEffect
)
}
}
其中关键代码为:
ts
// 判断是否text-overflow, 如果是就显示tooltip
const cellChild = (event.target as HTMLElement).querySelector(
'.cell'
) as HTMLElement
if (
!(
hasClass(cellChild, `${namespace}-tooltip`) &&
cellChild.childNodes.length
)
) {
return
}
// 利用Range判断是否超出显示范围
const range = document.createRange()
range.setStart(cellChild, 0)
range.setEnd(cellChild, cellChild.childNodes.length)
const rangeWidth = range.getBoundingClientRect().width
const padding =
(Number.parseInt(getStyle(cellChild, 'paddingLeft'), 10) || 0) +
(Number.parseInt(getStyle(cellChild, 'paddingRight'), 10) || 0)
if (
rangeWidth + padding > cellChild.offsetWidth ||
cellChild.scrollWidth > cellChild.offsetWidth
) {
// ...
}