在項(xiàng)目中,經(jīng)常會(huì)遇到文本超出問題留荔,通常的解決辦法是超出顯示省略號(hào),要么手動(dòng)截取文本豌习,要么設(shè)置css樣式存谎。在此我封裝了一個(gè)組件可以自動(dòng)使多行文本超出部分顯示為省略號(hào),本文主要記錄了思路肥隆,如果嫌我廢話太多可直接下拉至最后代碼(簡(jiǎn)書竟然不能設(shè)置錨點(diǎn)真是...)既荚。
常用到的單行文本超出解決辦法:
{
overflow: hidden;
text-overflow: ellipsis;
white-space:nowrap;
}
我本以為text-overflow也可以設(shè)置多行文本,于是最開始的思路就是用元素的line-height 乘以設(shè)置的行數(shù)rows栋艳,得到高度恰聘,然后手動(dòng)設(shè)置元素高度,超出部分自動(dòng)顯示省略號(hào)豈不是美滋滋,就可以拿去跟同事裝逼了晴叨,UI妹子可能就會(huì)多看我一眼了凿宾。沒想到剛一出馬就遇到了問題,element.style的方式是取不到css設(shè)置的樣式的兼蕊。要使用如下方法(我沒做IE兼容)
/*
element:你的元素初厚,
attribute:css樣式名,駝峰形式
*/
/*非IE瀏覽器*/
window.getComputedStyle(element)[attribute]
/*IE瀏覽器 */
element.currentStyle[attribute]
但是我太高估了text-overflow,這種思路可以實(shí)現(xiàn)文字截取孙技,但是不會(huì)自動(dòng)出現(xiàn)省略號(hào)产禾。
于是我決定集百家之眾長(zhǎng),不能閉(dan)門(wu)造(zhuang)車(bi)牵啦,就去百度了一下亚情,發(fā)現(xiàn)webkit內(nèi)核的瀏覽器可以直接用css樣式設(shè)置多行文本超出部門自動(dòng)顯示省略號(hào),如下所示
/*webkit-line-clamp設(shè)置行數(shù)即可*/
{
display:-webkit-box;
webkit-line-clamp: 2;
webkit-box-orient: vertical;
}
我不禁痛心疾首哈雏,感覺自己全做了無用功楞件,再也得不到UI妹子的愛了 ,但是轉(zhuǎn)念一想裳瘪,那非webkit內(nèi)核的瀏覽器怎么辦土浸,于是決定寫一個(gè)兼容的方法。
最開始的思路是彭羹,根據(jù)字體大小和元素寬度栅迄,取到單行字?jǐn)?shù),即設(shè)定行數(shù)時(shí)可以得到元素能容納的字?jǐn)?shù)皆怕,這樣做文本截取即可,試驗(yàn)后發(fā)現(xiàn)不同字符的占寬明顯不同西篓,比如單個(gè)漢字就明顯比單個(gè)字母或者數(shù)字占寬要大愈腾,思路流產(chǎn)。
后來轉(zhuǎn)念一想岂津,既然我可以拿到實(shí)時(shí)高度虱黄,我何不每次刪一個(gè)字符就算一遍高度。我可以拿到設(shè)定行數(shù)和行高吮成,所以可以拿到最終呈現(xiàn)的元素的高度橱乱,這樣每次拿實(shí)時(shí)的高度與此高度進(jìn)行比較,若實(shí)時(shí)高度不大于最終高度粱甫,即可實(shí)現(xiàn)文字截取泳叠,此時(shí)我在尾部添加一個(gè)省略號(hào)豈不美哉。試驗(yàn)了一下發(fā)現(xiàn)可行茶宵,即為最終方案危纫,代碼如下
html部分
<div
class="jc-textBox"
rows="1"
style="width:100px"
>
111111111111111111111111111111111111111
</div>
<div
class="jc-textBox"
rows="3"
style="width:100px"
>
啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦
</div>
<div
class="jc-textBox"
rows="3"
style="width:100px"
>
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</div>
css部分
.jc-textBox {
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1;
}
js部分
let textBoxs = $('.jc-textBox'),
tbLength = textBoxs.length;
//獲取元素的當(dāng)前樣式
const getCurrentStyle = (element,attribute) => {
return window.getComputedStyle(element)[attribute];
}
//獲取當(dāng)前行數(shù)設(shè)置下的最大高度
const getMaxHeight = (element,rows) => {
let lineHeight = getCurrentStyle(element,'lineHeight');
let number = 0;
if(lineHeight === 'normal'){
let fontSize = getCurrentStyle(element,'fontSize');
number = getNumber(fontSize) * 1.2;
}else {
number = getNumber(lineHeight);
}
return number * rows;
}
//當(dāng)元素的現(xiàn)有高度大于最大高度時(shí),就刪除字符,直到現(xiàn)有高度不大于最大高度
const removeLastChar = (element,maxHeight) => {
let end = false;
let text = element.innerText;
let textArr = text.split('');
while(!end){
textArr.pop();
let newText = textArr.join('');
element.innerText = newText + '...';
let currentHeight =getCurrentStyle(element,'height');
currentHeight = getNumber(currentHeight);
if(currentHeight <= maxHeight){
end = true;
}
}
}
//獲取屬性中的數(shù)字
const getNumber = (str) => {
let number = parseFloat(str);
number = Math.ceil(number);
return number;
}
for(let i = 0;i<tbLength;i++){
let textBox = textBoxs[i];
let options = {
rows: parseInt(textBox.getAttribute('rows')),
isSupportLineClamp: typeof(textBox.style.webkitLineClamp) != 'undefined',
}
textBox.title = textBox.innerText;
let rows = options.rows;
let maxHeight = getMaxHeight(textBox,rows);
if(options.isSupportLineClamp){
textBox.style.webkitLineClamp = rows;
textBox.style.display = '-webkit-box';
textBox.style.webkitBoxOrient = 'vertical';
}else {
let height = getCurrentStyle(textBox,'height');
height = getNumber(height);
if(height > maxHeight){
removeLastChar(textBox,maxHeight);
}
}
}
測(cè)試效果
chrome
firefox
注:firefox默認(rèn)樣式時(shí)中文的行高乘行數(shù)不等于元素高度种蝶,至今不知道為啥契耿,可以通過顯式的設(shè)置line-height或者改變font-family來解決,我用了第一種辦法螃征。
好了搪桂,我要去裝逼了。