前端技巧:检测到省略号文本自动显示 Tooltip
前言
在前端开发中,我们经常会遇到接口返回的文本内容过长,无法完全显示的问题。为了处理这一问题,通常会设置固定的宽度并使用省略号样式(text-overflow: ellipsis)来隐藏超出的文本。然而,有时产品需求还希望用户能够通过悬停查看完整内容,这时就需要引入 Tooltip 进行展示。(没被省略的时候不要显示Tooltip)
// tailwind的样式单行省略.line-clamp-1 {overflow: hidden;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 1;}// 自行设置的css样式single-line {overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
为了解决这个问题,我们实现了一个自定义 Hook,该 Hook 会监测文本元素是否因宽度限制而被省略。一旦检测到文本内容被省略,Hook 会自动为该元素添加 Tooltip,确保用户可以方便地查看完整信息。
代码实现
use-ellipsis.ts
import { useEffect, useRef, useState } from 'react';type Options = {lines?: number; // 支持多行};export function useEllipsis<T extends HTMLElement>({lines = 1,}: Options = {}) {const ref = useRef<T>(null);const [isEllipsis, setIsEllipsis] = useState(false);useEffect(() => {const el = ref.current;if (!el) return;const check = () => {if (lines === 1) {setIsEllipsis(el.scrollWidth > el.clientWidth);} else {setIsEllipsis(el.scrollHeight > el.clientHeight);}};check();window.addEventListener('resize', check);return () => {window.removeEventListener('resize', check);};}, [lines]);return { ref, isEllipsis };}
ellipsis-tooltip.tsx
import { Tooltip } from '@arco-design/web-react'; // 或 antd / 你自己的库import { useEllipsis } from '@/hooks/use-ellipsis.ts';import { cn } from '@/lib/utils.ts';type EllipsisTooltipProps = {text: string;className?: string;onClick?: () => void;lines?: number;};export const EllipsisTooltip: React.FC<EllipsisTooltipProps> = ({text,className,onClick,lines = 1,}) => {const { ref, isEllipsis } = useEllipsis<HTMLDivElement>({ lines });const lineClass =lines === 1 ? 'truncate whitespace-nowrap' : `line-clamp-${lines}`;const content = (<divref={ref}className={cn(lineClass,className)} onClick={onClick}>{text}</div>);return isEllipsis ? <Tooltipcontent={text}>{content}</Tooltip> : content;};
使用示例与效果
export default function TestPage() {const mockText = '很长很长很长很长很长';const mockText2 = '简短的';return (<><EllipsisTooltipclassName='w-28'text={mockText} /><EllipsisTooltiptext={mockText2} /></>);}