最多顯示三行,多餘...展開,點擊展開收起 getClientRects

需求:顯示文本,最多顯示三行,多餘的顯示 ... 展開,點擊展開收起.javascript

效果以下:css



須要考慮的點:換行,展開的時候遮住收起html



若是是不須要有固定在右側的展開收起,那麼移動端直接用css3:java

overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical

以前想過用屏幕寬度減去兩邊留白  除以字體大小,得出每一行能夠顯示多少行字。css3

var oneCount = Math.floor((window.innerWidth - 55-15 ) / 16),
function getStrByteLen(v) {
    //一箇中文按照兩個字節算,返回長度  return v ? v.replace(/[\u00FF-\uFFFF]/g, " ").length : 0;
}

然而須要考慮的因素不少:web

一、頭部有標籤,得加入計算dom

二、有換行ide

三、單行可顯示的字符數不是恰好對應上,如能夠顯示3個字符,那麼「aa中",則中字換行。字體

……spa

等等老是很難達到比較滿意的效果。顯示總有出入。

真正解決問題是使用

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;
}