文字超長,實現展開收起功能...

深山螞蟻發表於2018-08-20

對於超長文字,有時需要實現...功能。如果...不需要獲取事件,直接用css3來實現:

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

如果需要獲取事件,點選還能展開,怎麼處理呢?

1、計算螢幕可現實寬度,然後看一行可以顯示多少個字元,然後擷取顯示。

    這個就有點複雜了,需要考慮的點很多:

    a)中文,英文字元,

    b)換行符

    c)自定義表情(如果有<img實現的)。

    d)每一行最後位置不夠後面一個完整字元顯示,可能下一個字元是中文,可能下一個字元是英文。

2、使用getClientRects來精確做到。一個一個字元的減少,然後獲取當前有多少行,當達到所需要的行數,則OK了,把減少的隱藏。

fn.handleTxt = function() {
        var self = this;
        var dom = document.querySelectorAll(".item[data-id]");
        function removeA(index) {
            dom[index].removeAttribute("data-id");
        }
        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=self.feedObj.openText,len2=self.feedObj.feedlist.length;j<len2;j++){
                if(self.feedObj.feedlist[j].shareid==shareid){
                    obj = self.feedObj.feedlist[j];
                    break;
                }
            }
            if(!obj.showTxt){
                removeA(i);
                continue;
            }
            var rect = dom[i].getClientRects();
            var h = getLength(rect);
            if(h<3){
                removeA(i);
                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;
                }else{
                    var reg = t.match(/<img[^>]*>$/);//如果是<img xxxxxx > 則需要整體前移,否則會折斷
                    if(reg&&reg[0]) step = reg[0].length;
                }
                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(".item_more").offsetWidth;
                obj.hideTxt+=(rect[rect.length-1].width>(dom[i].offsetWidth-height)?'<span style="display:inline-block;width:'+height+'px"></span>':'');//頁面收起和正文重疊
            }else{
                dom[i].querySelectorAll(".dot").forEach(function (el) {
                    el.style.display="none";//把點點和展開放開,為後面計算更真實
                });
            }
            obj.showTxt = t;
            obj.txtDone = 1;
            removeA(i);
        }
        self.feedObj.openText = self.feedObj.feedlist.length;
    }
    function getLength(list){
        var l = 0, lastBottom;
        for(var i=0,len=list.length;i<len;i++){
            if(list[i].bottom == lastBottom){
                return;
            }
            lastBottom = list[i].bottom;
            l++;
        }
        return l;
    }

效果圖:

相關文章