一般的省略實現方式
經常會遇到多行文本省略變成...的形式的開發(fā)要求琢唾,并且基于用戶體驗的角度出發(fā),還需要對于文本有對應展開與收起的操作按鈕桅滋。
1.使用css屬性
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
或者
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
都只是實現了...的省略功能慧耍,達不到需求的目的。
2.通過js都是判斷固定的長度(但是div或者span往往長度不固定)切割省略丐谋,總是會有一個字符或者兩個字符留白或者部分機型剛好換行的芍碧,沒有很好實現需求。
基于getClientRects()的實現方式
1.getClientRects()的作用就是獲取元素占據頁面的所有矩形區(qū)域号俐。
var rect = document.getElementById('#rect');
console.log(rect)
//bottom: 58 height: 19 left: 20 right: 330.578125 top: 39 width: 310.578125 x: 20 y: 39
返回值是ClientRect對象集合泌豆,該對象是與該元素相關的CSS邊框。每個ClientRect對象包含一組描述該邊框的只讀屬性——left吏饿、top踪危、right和bottom蔬浙,單位為像素,這些屬性值是相對于視口的top-left的贞远。即使當表格的標題在表格的邊框外面畴博,該標題仍會被計算在內。
起初蓝仲,微軟打算讓這個方法給文本的每一行都返回一個TextRectangle俱病,但是,CSSOM工作草案規(guī)定它應該給每個邊框返回一個ClientRect袱结。因此亮隙,對于行內元素這兩個定義是相同的,但是對于塊級元素垢夹,Mozilla只會返回一個矩形溢吻。(譯者注:對于行內元素,元素內部的每一行都會有一個邊框促王;對于塊級元素,如果里面沒有其他元素硼砰,一整塊元素只有一個邊框)欣硼。
2.行內元素通過getClientRects()就能獲取到當前文本多少行题翰,只要通過遍歷,每次減少1個長度(br標簽減少5)诈胜,不斷計算是否是所需要的行數即可(例如文本5行,我需要3行省略焦匈,只要讓對于的span剛好是3行就可以,這樣就得到一個省略的文本了)
基于jQuery的方法實現如下:
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>完美版本的展開收起...</title>
<style>
*{margin: 0;
padding: 0;}
div {
width: 700px;
height: auto;
font-size: 14px;
color: #333;
background-color: #fafafa;
padding: 20px;
}
span.text-fold {
display: inline;
color: #4293f4;
cursor: pointer;
}
span.col-333 {
color: #333;
font-size: 14px;
line-height: 20px;
}
</style>
</head>
<body>
<div>
<span class="">春 ——朱自清:<br /></span>
<span class="break-word col-333" id="txt" style="display: inline;"
> 盼望著缓熟,盼望著累魔,東風來了,春天的腳步近了够滑。<br>
一切都像剛睡醒的樣子,欣欣然張開了眼彰触。山朗潤起來了,水漲起來了分蓖,太陽的臉紅起來了。<br>
小草偷偷地從土地里鉆出來么鹤,嫩嫩的,綠綠的午磁。園子里,田野里,瞧去衙熔,一大片一大片滿是的。坐著框咙,躺著痢甘,打兩個滾喇嘱,踢幾腳球塞栅,賽幾趟跑,捉幾回迷藏作烟。風輕悄悄的砾医,草軟綿綿的。<br>
桃樹如蚜,杏樹,梨樹探赫,你不讓我兴猩,我不讓你,都開滿了花趕趟兒。紅的像火讨勤,粉的像霞,白的像雪潭千。花里帶著甜味屉来;閉了眼狈癞,樹上仿佛已經滿是桃兒,杏兒蝶桶,梨兒≌媸花下成千成百的蜜蜂嗡嗡的鬧著,大小的蝴蝶飛來飛去战秋。野花遍地是:雜樣兒讨韭,有名字的,沒名字的拐袜,散在草叢里像眼睛像星星,還眨呀眨的蹬铺。<br>
“吹面不寒楊柳風”甜攀,不錯的秋泄,像母親的手撫摸著你规阀,風里帶著些新翻的泥土的氣息,混著青草味兒歧胁,還有各種花的香,都在微微潤濕的空氣里醞釀屠缭。鳥兒將巢安在繁花嫩葉當中崭参,高興起來了,呼朋引伴的賣弄清脆的歌喉何暮,唱出婉轉的曲子,跟清風流水應和著跨新。牛背上牧童的短笛贰军,這時候也成天嘹亮的響著。<br>
雨是最尋常的词疼,一下就是三兩天帘腹。可別惱舵盈∏蚧看,像牛毛筒愚,像花針,像細絲句伶,密密地斜織著陆淀,人家屋頂上全籠著一層薄煙。樹葉卻綠得發(fā)亮楚堤,小草也青得逼你的眼。傍晚時候身冬,上燈了,一點點黃暈的光拗小,烘托出一片安靜而和平的夜樱哼。在鄉(xiāng)下,小路上搅幅,石橋邊,有撐著傘慢慢走著的人息裸,地里還有工作的農民沪编,披著蓑戴著笠。他們的房屋稀稀疏疏的访圃,在雨里靜默著相嵌。<br>
天上的風箏漸漸多了,地上的孩子也多了饭宾。城里鄉(xiāng)下,家家戶戶徽鼎,老老小小性湿,也趕趟似的,一個個都出來了肤频。舒活舒活筋骨,抖擻抖擻精神汁雷,各做各的一份事兒去。
“一年之計在于春”挖藏,剛起頭兒厢漩,有的是功夫,有的是希望溜嗜。<br>
春天像剛落地的娃娃,從頭到腳都是新的辟躏,它生長著土全。<br>
春天像小姑娘,花枝招展的瑞凑,笑著走著概页。<br>
春天像健壯的青年,有鐵一般的胳膊和腰腳绰沥,領著我們向前去贺待。</span
>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
<script src="../js/rectOmitText.js"></script>
<script>
$(function(){
$('#txt').rectOmitText({
line: 5,
foldText: '隱藏',
unfoldText: '更多',
foldClass: 'text-fold'
});
})
</script>
</div>
</body>
</html>
基于jquery實現的rectOmitText.js:
/*
* getClientRects()只是支持行內元素麸塞,非行內元素不支持該方法
* unfoldText 展開文本
* foldText 收起文本
* unfoldClass 展開類名
* foldClass 收起類名
* line 多少行省略
* color 默認樣式顏色
*/
(function ($) {
$.fn.rectOmitText = function (options) {
if ($(this).css("display") != "inline") {
console.warn(
"該方法不支持非行內(inline)元素展開收起以及省略,奥此!請把對應的元素轉為inline元素"
);
return false;
}
var defaluts = {
unfoldText: "展開",
foldText: "收起",
unfoldClass: "",
foldClass: "",
line: 1,
color: "style='color: #2a68c9;'",
};
var opt = $.extend(defaluts, options);
var txtHtml = $(this).html(); //所有文本
var omitHtml = $(this).html(); //省略文本
var rect = $(this)[0].getClientRects(); //獲取元素占據頁面的所有矩形區(qū)域
console.log(rect)
var line = getLineLen(rect); //文本真實的行數
//展開顯示文本
var unfold = opt.unfoldClass
? "<span>... </span><span class='rect-unfold " +
opt.unfoldClass +
"'>" +
opt.unfoldText +
"</span>"
: "<span>... </span><span " +
opt.color +
" class='rect-unfold " +
opt.unfoldClass +
"'>" +
opt.unfoldText +
"</span>";
//收起顯示文本
var fold = opt.foldClass
? "<span class='rect-fold " +
opt.foldClass +
"'>" +
opt.foldText +
"</span>"
: "<span " +
opt.color +
"class='rect-fold " +
opt.foldClass +
"'>" +
opt.foldText +
"</span>";
if (line && line == 1) {
console.warn("標簽文本內容只有一行雁比,不作省略!");
return false;
}
if (opt.line >= line) {
console.warn("傳入的省略行數大于文本行數蠢终,不作省略");
return false;
}
//行數大于5行,顯示... 展開按鈕
while (line > opt.line) {
var step = 1;
if (/<br\/>$/.test(omitHtml)) {
//回退的時候程奠,如果碰到換行要整體替換
step = 5;
}
//每次減少文本數組最后以為參數(br標簽直接減少整個br標簽的長度)
omitHtml = omitHtml.slice(0, -step);
txt.innerHTML = omitHtml + unfold;
//更新行數
line = getLineLen($(this)[0].getClientRects());
if (omitHtml.length <= 0) {
//強制停止循環(huán)
break;
}
}
//展開點擊
$("#txt").on("click", "span.rect-unfold", function () {
$("#txt").html(txtHtml + fold);
});
//收起點擊
$("#txt").on("click", "span.rect-fold", function () {
$("#txt").html(omitHtml + unfold);
});
function getLineLen(arr) {
//獲取當前文本真實的行數祭钉,如果是<br>符號getClientRects()方法也會變成一個區(qū)域
var line = 0;
var bottom = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i].bottom != bottom) {
bottom = arr[i].bottom;
line++;
}
}
return line;
}
};
})(jQuery);
隱藏效果:
展開效果
注意
getClientRects()的方式僅僅支持行內元素(inline),塊級元素或者行內塊級元素都只是識別為一個矩形區(qū)域慌核,需要使用先把對應的標簽轉化為行內元素(inline)