问题
最近在使用 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>
);
};
实时获取文本是否溢出,借鉴了这篇文章# 判断文本是否溢出