博客 / 詳情

返回

前端技巧:檢測到省略號文本自動顯示 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 = (
    <div ref={ref} className={cn(lineClass, className)} onClick={onClick}>
      {text}
    </div>
  );

  return isEllipsis ? <Tooltip content={text}>{content}</Tooltip> : content;
};

使用示例與效果

export default function TestPage() {
  const mockText = '很長很長很長很長很長';
  const mockText2 = '簡短的';

  return (
    <>
      <EllipsisTooltip className='w-28' text={mockText} />
      <EllipsisTooltip text={mockText2} />
    </>
  );
}

ScreenShot_2026-01-07_102021_667

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文檔,大家一起討論學習,一起進步。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.