多行內(nèi)容超出...顯示的終極解決方案
點(diǎn)擊上方?前端瓶子君,關(guān)注公眾號
回復(fù)算法,加入前端編程面試算法每日一題群
最近遇到一個貌似很簡單,但寫起來也不簡單的問題。對于多行文字,超出...顯示。通過css可以實(shí)現(xiàn),但受限于瀏覽器兼容問題,有時候還需要依賴JS來實(shí)現(xiàn)。通過js實(shí)現(xiàn),就需要考慮到文字大小,中英文、數(shù)子、標(biāo)點(diǎn)符號所對應(yīng)的字節(jié)長度不一致,如果考慮的不全面,對于不同的文字內(nèi)容,總會有點(diǎn)差距。
首先,我們需要了解,中文漢字,英文字母,數(shù)字以及特殊符號所占的字節(jié)長度是不一樣的,如果需要計(jì)算準(zhǔn)確,就不能按照字符串的元素個數(shù)去截取,把它們換算成字節(jié)數(shù)來截取,準(zhǔn)確度更高。所以,我們需要一個獲取字符串字節(jié)長度的方法:
function?bitCompute(content)?{
??var?total?=?0,
??len?=?arguments[0].length?||?0
??for?(var?i?=?0;?i?????if?(content[i].charCodeAt()?>?255)?{
??????total?+=?2;
????}?else?{
??????total?+=?1;
????}
??}
??return?total
}
對于要截取多少內(nèi)容的字節(jié)數(shù),我們需要知悉能放入容器內(nèi)的字節(jié)數(shù)與總字節(jié)數(shù)的比例,展示字節(jié)數(shù)/總字節(jié)數(shù) = offsetWidth / scrollWidth:
function?complate()?{
??var?offsetWidth?=?el.offsetWidth;
??var?scrollWidth?=?el.scrollWidth;
??var?gap?=?scrollWidth?-?offsetWidth;
??var?percent?=?Math.floor(offsetWidth?/?scrollWidth?*?1e3)?/?1e3;
??return?{
????gap:?gap,
????percent:?percent
??}
}
根據(jù)計(jì)算得出的數(shù)據(jù),我們就可以操作字符串了
function?cut(content)?{
??el.innerHTML?=?content;
??var?info?=?complate(),
????percent?=?info.percent;
??var?total?=?bitCompute(content).total;
??var?showLen?=?+(total?*?percent).toFixed(0)?-?cfg.placeholder;
??content?=?bitCompute(content,?showLen).content;
??return?content?+?cfg.padding;
}
????????
function?bitCompute(content,?maxLen)?{
??var?total?=?0,
????len?=?arguments[0].length?||?0,
????outContent?=?'';
??for?(var?i?=?0;?i?????if?(content[i].charCodeAt()?>?255)?{
??????total?+=?2;
????}?else?{
??????total?+=?1;
????}
????if?(maxLen?&&?total?>?maxLen)?{
??????break;
????}
????outContent?+=?content[i];
??}
??return?{
????total:?total,
????content:?outContent
??}
}
當(dāng)然文字展示的多少,也是和字體大小相關(guān)的,所以我們也需要把字體大小的因素考慮到,而且作為一個工作方法,本身就不應(yīng)該頁面中的元素有關(guān)聯(lián),所以我們應(yīng)該在方法中自己創(chuàng)建元素,放入內(nèi)容,計(jì)算offsetWidth和scrollWidth
function?cutFactory(opt)?{
??var?cfg?=?{
????padding:?opt.padding?||?"...",
????classList:?opt.classList?||?[],
????style:?opt.style?||?{},
????debug:?opt.debug
??};
??cfg.placeholder?=?bitCompute(cfg.padding).total;
??var?el?=?doc.createElement("span");
??el.className?=?cfg.classList.join("?");
??var?customStyles?=?[];
??for?(var?styleKey?in?cfg.style)?{
????if?(cfg.style.hasOwnProperty(styleKey))?{
??????customStyles.push(styleKey?+?":"?+?cfg.style[styleKey]);
????}
??}
??el.style.cssText?=?"position:absolute;left:0;top:0;background:transparent;color:transparent;height:100%;white-space:nowrap;overflow:visible;border:0;"?+?(cfg.debug???"background:white;color:red;"?:?"")?+?customStyles.join(";");
??var?div?=?doc.createElement("div");
??div.appendChild(el);
??div.style.cssText?=?"width:99%;min-height:50px;line-height:50px;position:absolute;left:3px;top:3px;overflow:hidden;outline:0;background:transparent;"?+?(cfg.debug???"outline:1px?solid?red;background:black;"?:?"");
??doc.body.appendChild(div);
??var?css?=?win.getComputedStyle(el);
??cfg.fontSize?=?parseFloat(css.fontSize)?||?16;
????????
??return?function?(content)?{
????el.innerHTML?=?content;
????var?out?=?{
??????flag:?false,
??????cut:?'',
??????all:?content,
??????last:?content
????}
????if?(complate().gap?>?0)?{
??????out.flag?=?true,
??????out.last?=?out.cut?=?cut(content)
????}
????return?out
??}
}
最后,再暴露一個方法,方便使用者調(diào)用。為了性能考慮,不創(chuàng)建過多dom元素,我們可以緩存一下字體大小和容器寬度相同的截取方法
function?subStringEL(name,?fontSize,?width)?{
??this.subStringELFns?||?(this.subStringELFns?=?{});
??var?key?=?'key_'?+?fontSize?+?'_'?+?width;
??var?fn?=?this.subStringELFns[key];
??if?(!fn)?{
????fn?=?this.subStringELFns[key]?=?cutFactory({
??????style:?{
????????'font-size':?fontSize,
????????'width':?width
??????}
????})
??}
??return?fn(name);
}
這樣就完美的解決了多行超出...顯示的問題了,兼容性很好,而且也能準(zhǔn)確截取,靈活方便。希望能幫助到受該問題困擾的同仁,內(nèi)容中如有不正確之處,煩請指正,不勝感激! 另外附注源碼地址:
github地址:https://github.com/18822600748/MyJSFactory/blob/main/src/subStrByWidth.js[1]
參考資料
https://github.com/18822600748/MyJSFactory/blob/main/src/subStrByWidth.js: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2F18822600748%2FMyJSFactory%2Fblob%2Fmain%2Fsrc%2FsubStrByWidth.js
來自:夢想敲木魚
https://juejin.cn/post/7026655351004987400
最后
評論
圖片
表情
