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

组件-多行文本省略-展开收起

1、功能

需要实现下面的功能,多行文本出现省略,并且提供展开和收起按钮。

2、技术方案与实现

1、用-webkit-line-clamp 实现

-webkit-line-clamp 指定显示几行,然后display、overflow等等设置一下就好了。
省略号的位置非常正确,但是问题是兼容性一般,想在省略号后面加按钮就有点困难。

.text {overflow: hidden;display: -webkit-box;-webkit-line-clamp: 3;-webkit-box-orient: vertical;
}

2、用float手动实现

  1. 提供一个省略号的dom,然后设置为右浮动;
  2. text-container容器设置一个伪元素挤压文字和省略号,之后再让文字content上去(margin-top为负值)

问题:当一个单词不够显示距离时会完全消失,导致省略号和文本有很长的一段距离,可以用文本的截断解决,但是英文状态会把单词给截断,这样也不好。这个问题可以用绝对定位来解决,但是可能出现省略号遮住文字的问题。。。

代码如下:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><style>.text-container {width: 200px;height: 100px;overflow: hidden;}.text-container::before {content: '';display: block;height: 80px;}.content {margin-top: -80px;line-height: 24px;}.more {margin-right: 10px;float: right;line-height: 1;}</style><title>Document</title></head><body><div class="text-container"><div class="more">...</div><div class="content">瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁😀😍瑟尔华润国际hi哦平台警示牌日哦和家人屁</div></div></body>
</html>

效果如下:


3、react-组件

tsx:

import React, { memo, useEffect, useRef, useState } from 'react';
import CollapseText from './components/CollapseText';
import ExpendText from './components/ExpendText';
import styles from './index.scss';/*** 可展开文本组件的Props接口*/
interface Props {/** 要显示的文本内容 */text: string;/** 最大显示行数,超出后会截断显示省略号,默认为3行 */maxLines?: number;/** 自定义CSS类名 */className?: string;/** 收起按钮的文本,默认为"收起" */collapseText?: string | React.ReactNode;/** 展开按钮的文本,默认为"展开" */expandText?: string | React.ReactNode;/** 展开/收起回调 */onToggleExpansion?: (isExpanded: boolean) => void;
}/*** 可展开文本组件** 功能:* - 根据指定行数限制文本显示* - 超出行数时自动截断并显示展开按钮* - 支持展开/收起功能* - 支持自定义按钮文本** @param props - 组件属性* @returns React函数组件*/
const ExpandableText: React.FC<Props> = ({text,maxLines = 3,className = '',collapseText = <CollapseText />,expandText = <ExpendText />,onToggleExpansion,
}) => {// 控制文本是否展开的状态const [isExpanded, setIsExpanded] = useState(false);// 标记文本是否需要展开功能(即是否超出了指定行数)const [needsExpansion, setNeedsExpansion] = useState(false);// 文本容器的DOM引用,用于计算文本高度const textRef = useRef<HTMLDivElement>(null);const [peerContainerHeight, setPeerContainerHeight] = useState(0);const [containerHeight, setContainerHeight] = useState(0);/*** 检测文本是否超出指定的行数* 通过比较实际内容高度和最大允许高度来判断*/useEffect(() => {if (textRef.current) {// 获取当前元素的行高const lineHeight = parseInt(getComputedStyle(textRef.current).lineHeight);// 计算指定行数对应的最大高度const maxHeight = lineHeight * maxLines;setPeerContainerHeight(maxHeight);setContainerHeight(maxHeight);// 获取实际内容的滚动高度(包含被隐藏的部分)const actualHeight = textRef.current.scrollHeight;// 如果实际高度超过最大高度,则需要展开功能setNeedsExpansion(actualHeight > maxHeight);}}, [text, maxLines]); // 当文本内容或最大行数改变时重新检测/*** 切换文本展开/收起状态* @param e - 鼠标点击事件*/const toggleExpansion = (e: React.MouseEvent<HTMLButtonElement>) => {// 阻止事件冒泡,避免触发父级元素的点击事件e.stopPropagation();const newIsExpanded = !isExpanded;// 切换展开状态setIsExpanded(newIsExpanded);onToggleExpansion?.(newIsExpanded);// 切换展开状态时,更新容器高度if (newIsExpanded) {setContainerHeight(textRef.current?.clientHeight || containerHeight);} else {setContainerHeight(peerContainerHeight);}};return (<divclassName={`${styles['text-container']} ${className}`}style={{'--container-height': `${containerHeight}px`,'--line-height': `${24}px`,} as React.CSSProperties}>{needsExpansion && (// <span className={isExpanded ? styles.more : styles['more-position-expend']}><span className={styles['more']}>{!isExpanded && <span className={styles['more-text']}>... </span>}<span className={styles['more-button']} onClick={toggleExpansion}>{isExpanded ? collapseText : expandText}</span></span>)}<div ref={textRef} className={`${styles['content']}`}>{text}</div></div>);
};export default memo(ExpandableText);

 

css:

.text-container {height: var(--container-height);overflow: hidden;position: relative;
}
.text-container::before {content: '';display: block;height: calc(var(--container-height) - var(--line-height, 24px));
}.content {margin-top: calc((var(--container-height) - var(--line-height, 24px)) * -1);line-height: var(--line-height, 24px);
}
.more-position-expend {padding-left: 10px;position: absolute;bottom: 4px;right: 0;background: white;
}
.more {float: right;line-height: var(--line-height, 24px);
}
.more-text {font-size: 16px;
}
.more-button {margin-left: 4px;cursor: pointer;color: rgb(255, 34, 102);
}

3、END 

目前采用float的方式

http://www.dtcms.com/a/285977.html

相关文章:

  • VMC850立式加工中心Y轴传动机械结构设计cad【7张】三维图+设计说明书
  • 多模态大模型研究每日简报(2025-07-17)
  • 设计循环队列oj题(力口622)
  • 基于现代R语言【Tidyverse、Tidymodel】的机器学习方法与案例分析
  • OSPF路由协议的协商过程
  • (八)复习(拆分微服务)
  • 快速了解pycharm
  • 微服务基础环境搭建-centos7
  • HIVE实战处理(二十四)留存用户数
  • 第8天 | openGauss中一个数据库可以存储在多个表空间中
  • mybatisdemo(黑马)
  • 数据结构-3(双向链表、循环链表、栈、队列)
  • 前端-CSS (样式引入、选择器)
  • 7月18日总结
  • 深度学习之----对抗生成网络-pytorch-CycleGAN-and-pix2pix
  • Jenkins pipeline 部署docker通用模板
  • drm驱动学习(一)sunxi_drm初始化
  • 【leetcode】3201. 找出有效子序列的最大长度(1)
  • PyCharm 高效入门指南(核心模块详解二)
  • RoboBrain 2.0(具身智能论文阅读)
  • 笔试——Day12
  • 阿里云alicloud liunux3-安装docker
  • Python编程进阶知识之第二课学习网络爬虫(selenium)
  • JavaScript进阶篇——第九章 异常、this 与性能优化全解(终)
  • 14.链路聚合技术
  • 量化交易如何查询CFD指数实时行情
  • postman接口测试,1个参数有好几个值的时候如何测试比较简单快速?
  • IP协议深入理解
  • 20250718-4-Kubernetes 应用程序生命周期管理-Pod对象:实现机制_笔记
  • 如何保证缓存数据的一致性:数据库和缓存数据一致性,本地缓存和Redis缓存怎么保证数据一致性