【react + antd】表格列文本根据窗口自适应,溢出显示省略号

2,625 阅读1分钟

问题

最近在使用 antd 开发时有这么一个需求,表格列的文本宽度需要与列的宽度具有一定比例,且文本超出文本最大宽度后需要出现省略号,并有 Tooltip 提示。查了一会社区,没有发现能解决问题的文章,所以动手搞一搞。

分析一下可以得出关键点:

  • Tooltip 需要实时根据文本是否溢出来判断是否需要展示

思路

由于列的宽度会根据浏览器视窗的变化而改变,即文本的最大宽度也会跟着改变,这里可以用resize事件对窗口进行监听,实时判断文本是否溢出,然后判断是否需要有Tooltip 提示,对于省略号的样式

代码

上面讲的可能会有点乱,那就直接上代码

根据思路,需要写一个表格的列数据组件 AdaptiveCol

// isEllipsis 是一个boolean类型的state
// colRef 用来获取 span 元素
<div className='adaptiveCol'>
    <Tooltip title={isEllipsis ? text : ''}>
        <span ref={colRef} style={{ cursor: isEllipsis ? 'pointer' : 'default' }}>
            {text}
        </span>
    </Tooltip>
</div>

下面是样式

.adaptiveCol {
  span {
    display: inline-block;
    /* 最大宽度跟随列宽改变 */
    max-width: 90%;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

接下来写一个窗口监听函数,实时判断文本是否溢出

const [isEllipsis, setIsEllipsis] = useState<boolean>(false);
const colRef = useRef<any>();
const handleEllipsis = () => {
    // clientWidth 小于 scrollWidth 时为文本溢出
    if (colRef.current?.clientWidth < colRef.current?.scrollWidth) {
        setIsEllipsis(true);
    } else {
        setIsEllipsis(false);
    }
};
// 加个防抖,优化一下,这个就不写了网上有好多
const windowChange = debounce(handleEllipsis, 500);
useEffect(() => {
    handleEllipsis();
    window.addEventListener('resize', windowChange);
    return () => {
        window.removeEventListener('resize', windowChange);
    };
}, []);

这样就完成了这个需求。

完整代码如下

/**
 * 文本是否溢出 切换显示隐藏 Tooltip 提示
 */
const AdaptiveCol = ({ text }: PropsType) => {
  const [isEllipsis, setIsEllipsis] = useState<boolean>(false);
  const colRef = useRef<any>();
  const handleEllipsis = () => {
    if (colRef.current?.clientWidth < colRef.current?.scrollWidth) {
      setIsEllipsis(true);
    } else {
      setIsEllipsis(false);
    }
  };
  const windowChange = debounce(handleEllipsis, 500);
  useEffect(() => {
    // 第一次进入页面也需要知道文本是否溢出
    handleEllipsis();
    window.addEventListener('resize', windowChange);
    return () => {
      window.removeEventListener('resize', windowChange);
    };
  }, []);
  return (
    <div className='adaptiveCol'>
      <Tooltip title={isEllipsis ? text : ''}>
        <span ref={colRef} style={{ cursor: isEllipsis ? 'pointer' : 'default' }}>
          {text}
        </span>
      </Tooltip>
    </div>
  );
};

实时获取文本是否溢出,借鉴了这篇文章# 判断文本是否溢出