【React 轮子】文本溢出后显示展开/收起按钮


javascript 复制代码
/** hooks
 * 用于文本展示时判断是否展示 展开/收起按钮 (包含监听 文本变化/页面尺寸变换)
 * @param { string } text 需要展示的文本
 * @param { number } maxLength 文本最大展示行数
 * @param { number } lineHeight 文本行高 (单位 px)
*/ 
import React, { useEffect, useRef, useState } from 'react';
export const TruncatedText = ({ text,lineHeight,maxLength }) => {
	// 用于判断目前展开与否
  const [isTruncated, setIsTruncated] = useState(true);
  //是否需要显示 展开收起按钮
  const [shouldShowMore, setShouldShowMore] = useState(false);
  
  const containerRef = useRef(null);

  useEffect(() => {
      const checkTruncation = () => {
          if (containerRef.current) {
            const { scrollHeight } = containerRef.current;
              setShouldShowMore(scrollHeight > lineHeight*maxLength);
          }
      }; 
      checkTruncation(); // 初次检查
    	// 监听页面缩放
      const resizeObserver = new ResizeObserver(checkTruncation);
      if (containerRef.current) {
          resizeObserver.observe(containerRef.current);
      }

      return () => {
          if (containerRef.current) {
              resizeObserver.unobserve(containerRef.current);
          }
      };
  }, [text]);

  const toggleTruncate = () => {
      setIsTruncated((prev) => !prev);
  };
 
  return (
    <div
      style={{
        position: 'relative',
        display: '-webkit-box',
        overflow: 'hidden',
        maxHeight: isTruncated ? `calc(${lineHeight}px * ${maxLength})` : 'none',
        transition: 'max-height 0.2s ease',
        fontSize: '14px',
        lineHeight: `${lineHeight}px`,
      }}
    >
      <span ref={containerRef} style={{display:'inline-block'}} >
        {text}
      </span>
      {shouldShowMore && (
          <a
            onClick={toggleTruncate}
            style={{
              background: '#fff',
              position: 'absolute',
              bottom: 0,
              right: 0,
            }}
          >
              {isTruncated ? ' -展开' : '收起'}
          </a>
      )}
    </div>
  );
};
相关推荐
梦曦i4 分钟前
uni-app x下自研架构的工程化突围
前端·架构·uni-app x
速易达网络18 分钟前
ECharts 图表制作完全指南:从零到可视化实战
前端·javascript·echarts
IT_陈寒21 分钟前
SpringBoot多环境配置把我坑惨了,这个踩坑经验你最好看看
前端·人工智能·后端
徐小夕34 分钟前
深度剖析 30k star 的编码 Agent DeepSeek-Reasonix:长会话 Token 成本直降 80%
前端·vue.js·github
轻松西西莱尔37 分钟前
谷歌+斯坦福+CMU 等五家 203 页综述,我做了个HTML把主动式AI的边界跑给你看
前端·html·agent
吴凡wudianmei1 小时前
从 0 搭一个 AI Agent(四):SSE 跑通之后,三处“契约错配”与它们的修复边界
前端·后端·aigc
不可能片场1 小时前
Electron 发布 别拿 load 事件当页面就绪
前端·electron
paopaokaka_luck1 小时前
灾害应急物资管理系统(AI应急助手、Echarts可视化数据看板、捐赠入库联动、 物资全流程管理、库存变动追溯、灾情资讯与互动反馈、物资发放公示)
java·前端·javascript·spring boot·mysql·tomcat·echarts
kyriewen1 小时前
我验了 7 种 sticky 失效说法:3 种根本不成立
前端·javascript·程序员
程序边界1 小时前
一台数据集成软件的拆解笔记(下):一致性、容错、跑批与迁移,KFS 真正难的地方在这
java·前端·笔记