稀土掘金技术社区

前端技巧:检测到省略号文本自动显示 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} />    </>  );}
Image
图片
点击"阅读原文"了解详情~