Skip to content

element-plus如何实现内容超出时显示浮层

前言

同事接到需求:在 el-table-header 中实现 el-table-columnshow-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
) {
  // ...
}

参考