当前位置: 首页 > article >正文

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

在这里插入图片描述
在这里插入图片描述

/** 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>
  );
};


http://www.kler.cn/a/377548.html

相关文章:

  • 项目审核系统 ---(连接数据库---项目模拟)
  • 高德地图美食
  • Node.js 入门指南:从零开始构建全栈应用
  • 为什么我们调用 start()方法时会执行 run()方法 ,为什么我们不能 直接调用 run()方法?
  • python 获取鼠标点击的实时位置案例
  • el-table 滚动条重置 手动控制滚动条
  • java jsoup解析豆瓣电影数据html实战教程
  • Linux云计算 |【第五阶段】CLOUD-DAY5
  • 2.WebSocket进阶: 深入探究实时通信的最佳实践与优化技巧
  • Rust 力扣 - 1652. 拆炸弹
  • 深入理解跨域资源共享(CORS)安全问题原理及解决思路
  • C++编程法则365天一天一条(27)std::initializer_list 轻量级初始化列表
  • OKHTTP断点续传
  • 【运输&加载码头】仓库新卸物料检测系统源码&数据集全套:改进yolo11-DRBNCSPELAN
  • 利用Docker Compose构建微服务架构
  • 90%的读者都惊呆了!一键生成的微头条,连作者都认不出来是AI作品?
  • Linux常见指令大全(必要+知识点)
  • 设计模式08-行为型模式(命令模式/迭代器模式/观察者模式/Java)
  • 免公网服务器实现DDNS功能(API动态修改DNS解析IP)
  • webstorm 项目如何配置支持 nodejs
  • 怎么提取视频里的音频?关于提取视频里音频的几种方法
  • 【含文档】基于ssm+jsp的老年人健康管理系统(含源码+数据库+lw)
  • 移植 AWTK 到 纯血鸿蒙 (HarmonyOS NEXT) 系统 (4) - 平台适配
  • 计算机视觉和深度学习有什么区别
  • Leetcode21:合并两个有效链表
  • 关于Android Studio Http Proxy设置