【文本溢出】JS+React自定义省略号位置
作者:江月迟迟
发表于:2025-10-29
字数统计:776 字
预计阅读3分钟
背景
如果一个很长的数据需要展示,那么需要处理文本溢出,原生CSS支持在webkit内核的浏览器调用原生的API来实现省略号在末尾的功能。然而,如果这个数据的末尾很重要(中间不重要),那么省略号的位置应该调整在中间。
适用场景
- 需要显示文件类型
- 需要显示文件版本号(一般版本号在末尾)
- 需要显示文件哈希名(一般文件用哈希后缀定义唯一性)
实现
单行文本溢出,省略号在中间
tsx
const SingleEllipsisElement = ({ className, __html, value, type, suffix }) => {
// 使用 ref 来获取 DOM 元素
const contentRef = useRef(null);
// 在组件加载后动态设置后缀的 left 值
useEffect(() => {
const contentElement = contentRef.current;
if (contentElement) {
const contentWidth = contentElement.offsetWidth;
const suffixElement = contentElement.nextElementSibling; // 获取后缀 span
const parentElement = contentElement.parentElement; // 获取父元素
if (contentWidth < parentElement.offsetWidth) {
suffixElement.style.opacity = 0;
return;
} else {
suffixElement.style.opacity = 1;
suffixElement.style.left = `${parentElement.offsetWidth + 13}px`;
}
}
}, []);
return (
<div>
{__html ? (
<span ref={contentRef} dangerouslySetInnerHTML={{ __html }} />
) : (
<span ref={contentRef}>{value}</span>
)}
<span style={{ position: 'absolute', left: '0' }}>{`.${suffix}`}</span>
</div>
);
};多行文本溢出,省略号在中间
tsx
const MultiEllipsisElement = ({ className, __html, value, type }) => {
const containerRef = useRef(null);
useEffect(() => {
const container = containerRef.current;
if (!container) return;
const text = __html ? container.innerHTML : value;
const lineNum = 2; // 默认显示两行
const { width, fontSize } = window.getComputedStyle(container);
const containerWidth = parseFloat(width);
const textFontSize = parseFloat(fontSize);
const computedTextLength = (text: string) => {
let length = 0;
for (let i = 0; i < text.length; i++) {
if (text.charCodeAt(i) < 0 || text.charCodeAt(i) > 255) {
length += 2;
} else {
length += 1;
}
}
return length;
};
const sliceTextLength = (text: string, sliceLength: number) => {
let length = 0;
let newText = '';
for (let i = 0; i < text.length; i++) {
if (text.charCodeAt(i) < 0 || text.charCodeAt(i) > 255) {
length += 2;
} else {
length += 1;
}
if (length <= sliceLength) {
newText += text[i];
} else {
break;
}
}
return newText;
};
const lastSliceTextLength = (text: string, sliceLength: number) => {
let length = 0;
let newText = '';
for (let i = text.length - 1; i >= 0; i--) {
if (text.charCodeAt(i) < 0 || text.charCodeAt(i) > 255) {
length += 2;
} else {
length += 1;
}
if (length <= sliceLength) {
newText = text[i] + newText;
} else {
break;
}
}
return newText;
};
const textLength = computedTextLength(text);
const lineCharNum = Math.floor(containerWidth / textFontSize) * 2;
const totalStrNum = Math.floor(lineCharNum * lineNum);
let content = '';
if (textLength > totalStrNum) {
const middleIndex = Math.floor(
totalStrNum * ((lineNum * 2 - 1) / (lineNum * 2)),
);
content = `${sliceTextLength(text, middleIndex - 4)}...${lastSliceTextLength(text, totalStrNum - middleIndex - 1)}`;
} else {
content = text;
}
}, []);
return (
<div
ref={containerRef}
style={{
width: '100%',
overflow: 'hidden',
position: 'relative',
}}
>
{__html ? (
<div dangerouslySetInnerHTML={{ __html }} />
) : (
<div>{value}</div>
)}
</div>
);
};参考资料
(大佬!)前端文本溢出打点省略展示
单行和多行都有,但是稍微有点问题。纯css实现文本中间省略
这个写的也很好。CSS 文本超出提示效果
