在開發(fā)過程中,經(jīng)常會(huì)遇到文本超出顯示區(qū)域的情況,結(jié)合業(yè)務(wù)中的場景,簡單總結(jié)如下:
一行文本的省略
業(yè)務(wù)中常見場景
多行文本的省略
封裝成ellipsis指令或組件
一行文本的省略
css語法:
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
通常在開發(fā)中,有時(shí)候明明樣式已經(jīng)加上,卻仍然得不到想要的效果,仔細(xì)研究發(fā)現(xiàn),往往是代碼忽略掉兩個(gè)原則:
寬度(或隱式寬度,可以理解為通過繼承父級(jí)寬度得到的)
css要加到離文本內(nèi)容最近的塊級(jí)dom上
舉幾個(gè)簡單的例子,以下五種場景
<div class="ellipsis w200">
<p>
1、{{text}}
</p>
</div>
<div class="ellipsis w200">
<p class="inline">
2、{{text}}
</p>
</div>
<div class="ellipsis w200">
<p class="inline-block">
3、{{text}}
</p>
</div>
<div class="ellipsis w200">
<span>
4、{{text}}
</span>
</div>
<div class="w200">
<p class="ellipsis">
5、{{text}}
</p>
</div>
為什么會(huì)出現(xiàn)上述結(jié)果吶?
demo1 違反了原則2,css 要加到 p 標(biāo)簽上
demo3 同樣違反了原則2,因?yàn)?inline-block 同樣具有 block 的屬性
demo2 的 p 標(biāo)簽變?yōu)樾袃?nèi)元素后和 demo4 類似,而 demo5 的 w200 并沒有直接加到 p 標(biāo)簽上,但同樣起到了隱式寬度的效果
業(yè)務(wù)中常見場景
Table組件內(nèi)使用
要實(shí)現(xiàn)的效果:隨著瀏覽器窗口的變動(dòng),動(dòng)態(tài)展示出足夠多的文字
配合Table:table-layout: fixed 能幫助我們實(shí)現(xiàn)最終的效果
多行文本的省略
css語法:
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
存在兼容性問題,只能支持webkit內(nèi)核
js解決方案:
通過line-height * 行數(shù),得到文本高度
創(chuàng)建dom模擬渲染,得到截?cái)嗵幍奈谋咀鴺?biāo)
追加省略符號(hào)
function setEllipsis(el, binding, vnode) {
// 接收指令傳參(行數(shù)、是否設(shè)置title,行高)
const lineNum = binding.value.lines || 1;
const showTitle = binding.value.showTitle || false;
const lineHeight = binding.value.lineHeight || 22;
// 獲取顯示的文本內(nèi)容
const text = el.innerHTML;
if (!text.length) return;
// 是否顯示title
if (showTitle) el.setAttribute('title', text.trim());
// 獲取文本的行高
const computedStyle = window.getComputedStyle(el, null);
const textLineHeight = computedStyle.getPropertyValue('line-height') || lineHeight;
const textFontSize = computedStyle.getPropertyValue('font-size');
// 設(shè)置文本超出指定行數(shù)后隱藏樣式
const limitHeight = parseInt(textLineHeight) * lineNum;
if (limitHeight) {
el.style.height = `${limitHeight}px`;
el.style.overflow = 'hidden';
}
// 創(chuàng)建一個(gè)div按照同樣的樣式逐個(gè)字符顯示文本內(nèi)容,獲取到達(dá)指定行數(shù)時(shí)的字符下標(biāo)
const newDiv = document.createElement('div');
newDiv.style.width = `${el.clientWidth}px`;
newDiv.style.lineHeight = textLineHeight;
newDiv.style.fontSize = textFontSize;
newDiv.style.visibility = 'hidden';
document.body.appendChild(newDiv);
let targetIndex;
for (let i = 0, len = text.length; i < len; i++) {
newDiv.innerHTML = text.substring(0, i);
if (newDiv.clientHeight > limitHeight) {
targetIndex = i;
break;
}
}
document.body.removeChild(newDiv);
el.innerHTML = targetIndex ? `${text.substring(0, targetIndex - 3)}...` : text;
}
封裝成ellipsis指令或組件
省略指令v-ellipsis會(huì)接收3個(gè)參數(shù):
| 參數(shù) | 說明 | 類型
|:--------:| :-------------:|:-------------:|
| lines | 行數(shù) | number
|showTitle | 是否顯示title,文本超出顯示省略時(shí),當(dāng)鼠標(biāo)hover上去時(shí)是否在title上顯示完整的內(nèi)容 | boolean
|lineHeight | 行高,非必需 | number
具體使用如下:
<div class="example">
<div class="label">2:超出一行省略,hover顯示title</div>
<div v-ellipsis="{ lines: 1, showTitle: true }">
{{text}}
</div>
</div>
5、總結(jié)說明
當(dāng)實(shí)現(xiàn)文本省略時(shí)遵循如下原則
- 設(shè)置寬度(或隱式寬度,可以理解為通過繼承父級(jí)寬度得到的)
- css要加到離文本內(nèi)容最近的塊級(jí)dom上
對(duì)于多行文本的省略本文著重通過js的方案實(shí)現(xiàn),當(dāng)然如果你想追求css方案,可參考這篇文章
文中涉及到代碼可從這里獲取