先列出两个通用情况,当希望文本内容超出显示省略号时,可采取如下两种方式
一、单行文本
HTML 布局
<div class="overflow-text">
这是一行需要设置超出隐藏的文本内容
</div>
CSS 样式
.overflow-text {
overflow: hidden; /* 超出隐藏 */
white-space: nowrap; /* 文本不换行 */
text-overflow: ellipsis; /* 超出显示省略号 */
}
二、多行文本,在最后一行省略
HTML 布局
<div class="overflow-multi">
这是一段需要设置超出隐藏的文本内容,内容有点长,可能会放不下
</div>
CSS 样式
.overflow-multi {
overflow: hidden; /* 超出隐藏 */
word-break: break-all; /* 文本换行 */
text-overflow: ellipsis; /* 超出显示省略号 */
display: -webkit-box; /* 可灵活地调整子元素的大小和位置 */
-webkit-box-orient: vertical; /* 设置子元素的排列方向:vertical =>垂直;*/
-webkit-line-clamp: 2; /* 超出2行显示省略号 */
}
三、容器内有多个元素时,如何在最后打点
为了方便区分,我把每块小文案设置了不同的颜色,效果图如下:
先说一下设计思路(可以与下面的图对照着看,会更清晰一些)
-
首先要获取容器(即可视区域)的宽度
wrapWidth
-
需要知道容器内能放下几个元素
2.1 循环遍历子元素,并进行加和,记录实际总宽度
realWidth
2.2 与容器宽度进行对比
- 如果 实际总宽度 <= 容器宽度,则记录下来
- 否则 跳出循环
-
计算容器内还剩多少宽度,记为
diff
-
为可视区域范围内的下一个元素,限定宽度,设为值
diff
,即让它超出显示省略号Q:这里为什么不给最后一个元素限定宽度呢?
A:考虑到有可能是中间任意一个元素宽度超出。
比如下图,如果第三块橙色区域已经超出容器宽度,此时给最后一个元素限定宽度,是无法达到我们的预期的。
下面是实现方式
HTML 布局
<div class="overflow-wrap">
<span>这是一行</span>
<span>有多个元素</span>
<span>的文本</span>
<span>需要超出打点</span>
</div>
Typescript
/**
* 处理超出隐藏
* @param dom
*/
const handleOverflow = (dom: HTMLElement) => {
/** 容器宽度 */
const wrapWidth = dom.clientWidth
const children = Array.from(dom.children) as HTMLElement[]
// 获取每个子元素宽度,并记录map
const childWidthMap: { [key in string]: number } = {}
children.map((child, index) => {
const childWidth = child.clientWidth
childWidthMap[index] = childWidth
})
// 获取在父元素范围内的元素集合,并保存宽度
let realWidth = 0
const realChildWidths: number[] = []
for (const key in childWidthMap) {
const value = childWidthMap[key]
const temp = realWidth + value
/** 元素放不下时 跳出循环 */
if (temp > wrapWidth) break
realWidth += value
realChildWidths.push(value)
}
/** 容器内,除了能放下的元素外,还剩多少宽度 */
const diff = wrapWidth - realWidth
const realChildLength = realChildWidths.length
// 循环所有元素
children.map((child, index) => {
// 当前元素是可视区域内的最后一个,则设置超出隐藏
if (index === realChildLength) {
// 设置宽度变量,把宽度代码放在 css 里,可以支持屏幕自适应
child.style.setProperty("--overflow-width", diff + "px")
child.classList.add("overflow-item")
} else if (index > realChildLength) {
// 当前元素超出可视区域,则直接隐藏
child.classList.add("overflow-hide")
}
})
// 设置超出标识
if (realChildLength < children.length) {
dom.classList.add("is-over")
}
}
CSS 样式
.overflow-wrap {
display: flex;
overflow: hidden; /* 超出隐藏 */
white-space: nowrap; /* 文本不换行 */
}
.overflow-hide {
display: none;
}
.overflow-item {
overflow: hidden; /* 超出隐藏 */
white-space: nowrap; /* 文本不换行 */
text-overflow: ellipsis; /* 超出显示省略号 */
width: var(--overflow-width); /* 这里的宽度是 js 中为超出元素限定的宽度 */
}
如果更好的方案,欢迎各位大佬指教啦~