最多顯示三行,多餘...展開,點選展開收起 getClientRects
阿新 • • 發佈:2019-02-17
需求:顯示文字,最多顯示三行,多餘的顯示 ... 展開,點選展開收起.
效果如下:
需要考慮的點:換行,展開的時候遮住收起
如果是不需要有固定在右側的展開收起,那麼移動端直接用css3:
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical
之前想過用螢幕寬度減去兩邊留白 除以字型大小,得出每一行可以顯示多少行字。
var oneCount = Math.floor((window.innerWidth - 55-15 ) / 16),
function getStrByteLen(v) { //一箇中文按照兩個位元組算,返回長度 return v ? v.replace(/[\u00FF-\uFFFF]/g, " ").length : 0; }
然而需要考慮的因素很多:
1、頭部有標籤,得加入計算
2、有換行
3、單行可顯示的字元數不是剛好對應上,如可以顯示3個字元,那麼“aa中",則中字換行。
……
等等總是很難達到比較滿意的效果。顯示總有出入。
真正解決問題是使用
getClientRects
getClientRects這個方法如果是讀取div元素上的,則總是一行
那麼如下:<div class="txt"> 我是一個小文字, 我是一個小文字 </div>
document.querySelector(".txt").getClientRects()
讀取到的總是一行
需要把塊級元素div ---> 行內元素span
function handleTxt() { var dom = document.querySelectorAll(".quan_feed_desc[data-shareid]"); for(var i=0,len=dom.length;i<len;i++){ var shareid = dom[i].dataset.shareid; if(typeof shareid=="undefined") continue; var obj={}; for(var j=feedObj.openText,len2=feedObj.feedlist.length;j<len2;j++){//openText,記錄上次計算到哪裡了。 if(feedObj.feedlist[j].shareid==shareid){ obj = feedObj.feedlist[j]; break; } } var rect = dom[i].getClientRects(); var h = getLength(rect); if(h<3||!obj.showTxt){ dom[i].removeAttribute("data-shareid"); continue; } var tl=0,t = obj.showTxt; dom[i].querySelectorAll(".dot").forEach(function (el) { el.style.display="inline-block";//把點點和展開放開,為後面計算更真實 }); var showtxt = dom[i].querySelector(".showtxt"); while(h>3){ var step=1; if(/<br\/>$/.test(t)){//回退的時候,如果碰到換行要整體替換 step = 5; } t = t.slice(0,-step); showtxt.innerHTML = t; h = getLength(dom[i].getClientRects()); tl+=step; } obj.hideTxt =obj.showTxt.slice(obj.showTxt.length-tl); if(obj.hideTxt){ var height=dom[i].querySelector(".quan_feed_more").offsetWidth;//頁面展開更多的大小 obj.hideTxt+=(rect[rect.length-1].width>(dom[i].offsetWidth-height)?'<span style="display:inline-block;width:'+height+'px"></span>':'');//頁面收起和正文重疊 } obj.showTxt = t; obj.txtDone = 1; dom[i].removeAttribute("data-shareid"); } feedObj.openText = feedObj.feedlist.length; }
function getLength(list){
var line = 0, lastBottom=0;
for(var i=0,len=list.length;i<len;i++){
if(list[i].bottom ==lastBottom){
return;
}
lastBottom = list[i].bottom;
line++;
}
return line;
}