JS/React实现文本截断:用自定义SVG图标替换默认省略号
在JS/React中实现自定义SVG图标替代文本截断省略号
下面提供两种实用方案,分别应对简单场景和需要精准判断的复杂场景:
方案一:纯CSS快速实现(适合确定文本必溢出的场景)
这种方法无需JS逻辑,直接通过CSS伪元素替换默认省略号,但缺点是无法自动判断文本是否溢出——不管文本长短,图标都会显示。
实现代码
.truncate-container { width: 200px; /* 固定容器宽度 */ white-space: nowrap; overflow: hidden; position: relative; padding-right: 20px; /* 给SVG图标预留空间 */ } .truncate-container:after { content: ''; position: absolute; right: 0; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; /* 替换成你的自定义SVG,这里用示例SVG */ background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></svg>') no-repeat center; background-size: contain; }
// React中使用 const App = () => { return ( <div className="truncate-container"> This text here is way too long to fit in the container </div> ); };
方案二:React动态判断(精准适配所有场景)
通过React的Ref和状态管理,动态判断文本是否溢出,仅在需要截断时显示自定义SVG图标,同时保证截断后的文本+图标不会超出容器。
实现组件
import { useRef, useState, useEffect } from 'react'; const CustomTruncateText = ({ text, width = '200px', iconSize = 16 }) => { const containerRef = useRef(null); const [isOverflowing, setIsOverflowing] = useState(false); const [truncatedText, setTruncatedText] = useState(text); // 判断文本是否溢出并处理截断逻辑 const checkOverflow = () => { const container = containerRef.current; if (!container) return; // 先重置文本,获取真实的滚动宽度 container.textContent = text; const overflow = container.scrollWidth > container.clientWidth; setIsOverflowing(overflow); if (overflow) { // 逐步截断文本,给图标预留空间(根据字体调整偏移量) let tempText = text; const iconCharOffset = Math.floor(iconSize / 8); // 字体大小8px对应1个字符,按需调整 while (container.scrollWidth > container.clientWidth && tempText.length > 0) { tempText = tempText.slice(0, -1); container.textContent = tempText; } setTruncatedText(tempText); container.textContent = ''; // 清空容器,后续由React渲染 } else { setTruncatedText(text); } }; // 监听文本变化和窗口 resize useEffect(() => { checkOverflow(); const handleResize = () => checkOverflow(); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, [text, iconSize]); return ( <div ref={containerRef} style={{ width: width, whiteSpace: 'nowrap', overflow: 'hidden', display: 'inline-flex', alignItems: 'center', gap: '4px', // 文本和图标之间的间距 }} > {truncatedText} {isOverflowing && ( <svg width={iconSize} height={iconSize} viewBox="0 0 24 24" fill="currentColor"> {/* 替换成你的自定义SVG路径 */} <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/> </svg> )} </div> ); }; // 使用示例 const App = () => { return ( <div style={{ padding: '20px' }}> <CustomTruncateText text="This text here is way too long to fit in the container" width="250px" iconSize={18} /> <br /><br /> <CustomTruncateText text="Short text that fits perfectly" /> </div> ); }; export default App;
关键细节说明
- 使用
scrollWidth > clientWidth判断文本是否溢出,精准可靠 - 动态截断文本时预留图标空间,避免图标超出容器
- 添加窗口
resize监听,适配响应式场景 - 通过
inline-flex和align-items:center保证文本与SVG图标垂直对齐 - 支持自定义容器宽度、图标大小,灵活性高
内容的提问来源于stack exchange,提问作者OvalOlive
相关产品推荐
相关产品推荐

