新聞中心
在實(shí)際的開發(fā)中不管是移動端還是 PC 端都會遇到文本太長,因?yàn)閷挾炔粔驅(qū)е挛覀冃枰O(shè)置成省略號。文本就文本溢出做一個(gè)總結(jié),希望對你們開發(fā)過程中有幫助。

公司主營業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)建站是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)建站推出金湖免費(fèi)做網(wǎng)站回饋大家。
閱讀本文你將看到如下幾部分內(nèi)容:
- 單行文本溢出
- 多行文本溢出
- 拓展的多行文本溢出
- 自定義多行文本溢出
高亮多行文本溢出
單行文本溢出一行文本超出顯示是一個(gè)最基本的超出最大寬度,顯示省略號[1],效果如圖所示
這個(gè)效果通過 css 就可以實(shí)現(xiàn),代碼如下:
- width: 300px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- border:2px solid greenyellow;
兼容性一片綠呀,基本上所有的瀏覽器都支持
多行文本溢出
這個(gè)效果也可以通過 css 來實(shí)現(xiàn)
- width: 100px;
- overflow: hidden;
- text-overflow: ellipsis;
- display: -webkit-box;
- -webkit-line-clamp: 3;
- -webkit-box-orient: vertical;
- border: 2px solid greenyellow;
如果將 display: -webkit-box 和 text-overflow: ellipsis 配合使用,文本將以省略號結(jié)尾。
line-clamp 設(shè)置文本顯示的行數(shù)
box-orient 設(shè)置元素的排列方式
但是如果我們輸入的內(nèi)容是英文,如下圖所示:
我們會發(fā)現(xiàn)英文沒有如我所愿,顯示 3 行。因?yàn)橛⑽氖遣粫詣訐Q行的,所以我們需要設(shè)置換行
- word-wrap: break-word; //允許長單詞換行到下一行
- word-break: break-all; //允許在單詞內(nèi)換行
效果如下
兼容性:該方法不適用于 IE 瀏覽器。
改變思路采用定位+偽類方法
- div {
- position: relative;
- line-height: 20px;
- max-height: 60px;
- overflow: hidden;
- word-break: break-all;
- }
- div::after {
- content: "...";
- position: absolute;
- bottom: 0;
- right: 0;
- padding-left: 40px;
- background: -webkit-linear-gradient(left, transparent, #fff 55%);
- background: -o-linear-gradient(right, transparent, #fff 55%);
- background: -moz-linear-gradient(right, transparent, #fff 55%);
- background: linear-gradient(to right, transparent, #fff 55%);
- }
- 使用 line-height 和 max-height 來限制顯示的行數(shù),word-break 是設(shè)置英文單詞允許單詞內(nèi)換行;
- 在::after 中使用 background: linear-gradient 而不直接使用 background 可以避免文字顯示不全的問題;
- ::after 在 ie8 不支持可以采用:after,如果在 ie6,7 時(shí),::after 可以換成真實(shí)元素來替換如
效果如下:
兼容性
也可以使用封裝好的庫clamp-js-main[2]
- npm i clamp-js-main
效果如下:
拓展的多行文本溢出
在支持了多行文本溢出顯示省略號的功能之后,產(chǎn)品同學(xué)又發(fā)現(xiàn)體驗(yàn)不友好的點(diǎn),如下圖所示,文本在第二行開頭處就結(jié)束了,這就導(dǎo)致第二行大部分是空白的內(nèi)容,影響了美觀度。
因此,產(chǎn)品同學(xué)提出了一個(gè)新需求:
- 當(dāng)文本沒有超過第 x 行的一半時(shí),則按第 x-1 行溢出顯示省略號的方式展示;(第 1 行除外)
- 當(dāng)文本超過第 x 行的一半但沒有超過第 x 行時(shí),則正常展示;
- 當(dāng)文本超過第 x 行時(shí),則按第 x 行溢出顯示省略號的方式展示。
這就需要計(jì)算出文本實(shí)際占用的寬度才能選擇采用哪種展示方式。
查找資料得知,canvas 提供了一個(gè)measureText[3]的方法,該方法的返回包含一個(gè)對象,這個(gè)對象里包含了以像素計(jì)的指定字體寬度。
于是可以基于canvas[4]能力來實(shí)現(xiàn)這個(gè)功能,大概的流程圖如下圖所示。
這里最關(guān)鍵的是要計(jì)算出每一行可以顯示多少文本,利用 canvas 的 measureText 方法,可以達(dá)到這個(gè)效果,代碼如下
- //處理文字多出省略號顯示
- function dealWords(options) {
- options.ctx.font = options.fontSize + "px Arial";//設(shè)置字體大小
- var allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth);//實(shí)際總共能分多少行
- var count = allRow >= options.maxLine ? options.maxLine : allRow;//實(shí)際能分多少行與設(shè)置的最大顯示行數(shù)比,誰小就用誰做循環(huán)次數(shù)
- var endPos = 0;//當(dāng)前字符串的截?cái)帱c(diǎn)
- let textArr = [];
- for (var j = 0; j < count; j++) {
- var nowStr = options.word.slice(endPos);//當(dāng)前剩余的字符串
- var rowWid = 0;//每一行當(dāng)前寬度
- if (options.ctx.measureText(nowStr).width > options.maxWidth) {//如果當(dāng)前的字符串寬度大于最大寬度,然后開始截取
- for (var m = 0; m < nowStr.length; m++) {
- rowWid += options.ctx.measureText(nowStr[m]).width;//當(dāng)前字符串總寬度
- if (rowWid > options.maxWidth) {
- if (j === options.maxLine - 1) { //如果是最后一行
- textArr.push(nowStr.slice(0, m - 1) + '...');
- options.ctx.fillText(nowStr.slice(0, m - 1) + '...', options.x, options.y + (j + 1) * 18); //(j+1)*18這是每一行的高度
- } else {
- textArr.push(nowStr.slice(0, m))
- options.ctx.fillText(nowStr.slice(0, m), options.x, options.y + (j + 1) * 18);
- }
- endPos += m;//下次截?cái)帱c(diǎn)
- break;
- }
- }
- } else if (options.ctx.measureText(nowStr).width > options.maxWidth / 2 && options.ctx.measureText(nowStr).width < options.maxWidth) {//如果當(dāng)前的字符串寬度小于最大寬度就直接輸出
- textArr.push(nowStr.slice(0));
- options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 18);
- } else {
- if (j > 0) {
- if (options.ctx.measureText(nowStr).width < options.maxWidth / 2) {
- document.getElementById('myCanvas').height = 150;
- options.ctx.font = options.fontSize + "px Arial";//設(shè)置字體大小
- textArr.push(nowStr.slice(0));
- for (let n = 0; n < textArr.length - 1; n++) {
- if (n == j - 1) {
- options.ctx.fillText(textArr[n].slice(0, textArr[n].length - 1) + "...", options.x, options.y + (n + 1) * 18);
- } else {
- options.ctx.fillText(textArr[n], options.x, options.y + (n + 1) * 18);
- }
- }
- }
- }else{
- options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 18);
- }
- }
- }
- }
- var ctx = document.getElementById('myCanvas').getContext('2d');
- var name = '前端簡報(bào),前端簡報(bào),前端簡報(bào),前端簡報(bào),前端簡報(bào),前端簡報(bào),前端簡報(bào),前端。';
- this.dealWords({
- ctx: ctx,//畫布上下文
- fontSize: 18,//字體大小
- word: name,//需要處理的文字
- maxWidth: 300,//一行文字最大寬度
- x: 0,//文字在x軸要顯示的位置
- y: 0,//文字在y軸要顯示的位置
- maxLine: 3//文字最多顯示的行數(shù)
- })
效果圖 當(dāng)文本沒有超過第 x 行的一半時(shí),則按第 x-1 行溢出顯示省略號的方式展示;(第 1 行除外)
當(dāng)文本超過第 x 行的一半但沒有超過第 x 行時(shí),則正常展示;
當(dāng)文本超過第 x 行時(shí),則按第 x 行溢出顯示省略號的方式展示。
兼容性
自定義多行文本溢出
過一段時(shí)間之后,產(chǎn)品同學(xué)又提出了新的進(jìn)階版需求
- 文本的首行開頭需要縮進(jìn)或者可以配置一個(gè)圖標(biāo);
- 文本的末尾可以配置按鈕或者圖標(biāo),并且如果文本超過了范圍需要顯示省略號,但是省略號需要在按鈕或圖標(biāo)的前面。
類似于如圖所示:
推薦兩個(gè)封裝好的組件
HeyUI:https://www.heyui.top/component/other/textellipsis[5]
vue-text-ellipsis:https://github.com/Luobata/vue-text-ellipsis[6]
它們的思路都是通過最終展示的實(shí)際高度是否超過預(yù)期的容器高度來判斷是否需要刪減文本。其流程圖大概如下圖所示。
就這樣,通過現(xiàn)成的組件就解決了一個(gè)難題。
高亮多行文本溢出
有些文本表達(dá)的意思可能比較重要,這就需要重點(diǎn)引起用戶的注意。
而有些文本表達(dá)的意思可能重要程度一般,這就不需要用戶注意。
于是乎她們又提出了一個(gè)通過高亮文本來提升用戶體驗(yàn)的需求:
- 能夠根據(jù)文本的標(biāo)記進(jìn)行高亮展示
比方說,獲取到下面一段文本,它要顯示出入下圖所示的那樣高亮效果[7]。
由于文本高亮需要通過標(biāo)簽將文本包裹起來并添加高亮樣式才能實(shí)現(xiàn),而之前的組件是通過 v-text 的方式實(shí)現(xiàn)的,因此這里不能直接使用,需要將組件改造成 v-html 的方式插入才可以。
假如通過 v-html 插入文本,并且設(shè)置了 em 標(biāo)簽的樣式,那么就會有一個(gè)問題,組件是通過循環(huán)剔除最后一個(gè)字符直到實(shí)際高度小于容器高度來實(shí)現(xiàn)展示功能的,這就有可能截掉標(biāo)簽字符,導(dǎo)致最后的展示有異常。
所以,在截取文本的時(shí)候還需要做一些處理,流程圖如下圖所示。
到這里,已經(jīng)實(shí)現(xiàn)文本的一種高亮形式了,但是假如有好幾個(gè)部分的文本需要高亮且高亮的樣式還各不相同,這又要怎么解決呢?
一種思路是,通過幾種不同名稱的標(biāo)簽分別包裹需要高亮的文本,每一種標(biāo)簽會對應(yīng)一種高亮樣式,這樣的話,在獲得源文本后,首先通過詞法分析將源文本中的標(biāo)簽解析出來,后面的流程就跟上圖步驟 1 后面的流程類似了。
參考資料
[1]css 多行文字溢出打點(diǎn)省略號: https://blog.csdn.net/c_kite/article/details/81486953
[2]clamp-js-main: https://www.npmjs.com/package/clamp-js-main
[3]measureText: https://www.w3school.com.cn/tags/canvas_measuretext.asp
[4]微信小程序之canvas 文字?jǐn)嘈泻褪÷蕴栵@示: https://www.cnblogs.com/zjjDaily/p/9956848.html
[5]https://www.heyui.top/component/other/textellipsis: https://www.heyui.top/component/other/textellipsis
[6]https://github.com/Luobata/vue-text-ellipsis: https://github.com/Luobata/vue-text-ellipsis
[7]淺談移動端過長文本溢出顯示省略號的實(shí)現(xiàn)方案: https://mp.weixin.qq.com/s?__biz=MzI4NjY4MTU5Nw==&mid=2247486441&idx=2&sn=ce5cc6ba16db4d022f6768bcf896abed&chksm=ebd87b7bdcaff26da481dca06b58a96c8f4162bccbb571296c7568b45d80af549df1c520a1a7&token=69805300&lang=zh_CN#rd
【編輯推薦】
- 一文教你探測虛擬環(huán)境是物理機(jī)、虛擬機(jī)還是容器?
- 比較9款代碼質(zhì)量工具,看看哪款更好用
- 推薦十個(gè)好用的程序員摸魚網(wǎng)站,現(xiàn)在就給我玩起來!
- 2021年網(wǎng)絡(luò)安全趨勢:更高的預(yù)算,重點(diǎn)終端和云安全
- 為什么碼農(nóng)不應(yīng)該在面試中同意進(jìn)行編程測試
文章名稱:深入擴(kuò)展文本溢出解決方案
文章位置:http://m.fisionsoft.com.cn/article/dhccgpo.html


咨詢
建站咨詢
