詳解JS如何實(shí)現(xiàn)文字溢出時(shí)用省略號(hào)...顯示
前一陣做需求時(shí),有個(gè)小功能實(shí)現(xiàn)起來廢了點(diǎn)腦細(xì)胞,覺得可以記錄一下。
產(chǎn)品的具體訴求是:用戶點(diǎn)擊按鈕進(jìn)入詳情頁(yè)面,詳情頁(yè)內(nèi)的卡片標(biāo)題內(nèi)容過長(zhǎng)時(shí),標(biāo)題的前后兩端正常展示,中間用省略號(hào)...表示,并且鼠標(biāo)懸浮后,展示全部?jī)?nèi)容。
關(guān)于鼠標(biāo)懸浮展示全部?jī)?nèi)容的代碼就不放在這里了,本文主要寫關(guān)于實(shí)現(xiàn)中間省略號(hào)...的代碼。
實(shí)現(xiàn)思路
- 獲取標(biāo)題盒子的真實(shí)寬度, 我這里用的是clientWidth;
- 獲取文本內(nèi)容所占的實(shí)際寬度;
- 根據(jù)文字的大小計(jì)算出每個(gè)文字所占的寬度;
- 判斷文本內(nèi)容的實(shí)際寬度是否超出了標(biāo)題盒子的寬度;
- 通過文字所占的寬度累加之和與標(biāo)題盒子的寬度做對(duì)比,計(jì)算出要截取位置的索引;
- 同理,文本尾部的內(nèi)容需要翻轉(zhuǎn)一下,然后計(jì)算索引,截取完之后再翻轉(zhuǎn)回來;
代碼
html代碼
<div class="title" id="test">近日,銀行紛紛下調(diào)大額存單利率,但銀行定期存款仍被瘋搶。銀行理財(cái)經(jīng)理表示:有意向購(gòu)買定期存款要盡快,不確定利率是否會(huì)再降。</div>
css代碼: 設(shè)置文本不換行,同時(shí)設(shè)置overflow:hidden
讓文本溢出盒子隱藏
.title { width: 640px; height: 40px; line-height: 40px; font-size: 14px; color: #00b388; border: 1px solid #ddd; overflow: hidden; /* text-overflow: ellipsis; */ white-space: nowrap; /* box-sizing: border-box; */ padding: 0 10px; }
javascript代碼:
獲取標(biāo)題盒子的寬度時(shí)要注意,如果在css樣式代碼中設(shè)置了padding, 就需要獲取標(biāo)題盒子的左右padding值。 通過getComputedStyle
屬性獲取到所有的css樣式屬性對(duì)應(yīng)的值, 由于獲取的padding值都是帶具體像素單位的,比如: px
,可以用parseInt特殊處理一下。
獲取盒子的寬度的代碼,我當(dāng)時(shí)開發(fā)時(shí)是用canvas計(jì)算的,但計(jì)算的效果不太理想,后來逛社區(qū),發(fā)現(xiàn)了嘉琪coder
大佬分享的文章,我這里就直接把代碼搬過來用吧, 想了解的掘友可以直接滑到文章末尾查看。
判斷文本內(nèi)容是否超出標(biāo)題盒子
// 標(biāo)題盒子dom const dom = document.getElementById('test'); // 獲取dom元素的padding值 function getPadding(el) { const domCss = window.getComputedStyle(el, null); const pl = Number.parseInt(domCss.paddingLeft, 10) || 0; const pr = Number.parseInt(domCss.paddingRight, 10) || 0; console.log('padding-left:', pl, 'padding-right:', pr); return { left: pl, right: pr } } // 檢測(cè)dom元素的寬度, function checkLength(dom) { // 創(chuàng)建一個(gè) Range 對(duì)象 const range = document.createRange(); // 設(shè)置選中文本的起始和結(jié)束位置 range.setStart(dom, 0), range.setEnd(dom, dom.childNodes.length); // 獲取元素在文檔中的位置和大小信息,這里直接獲取的元素的寬度 let rangeWidth = range.getBoundingClientRect().width; // 獲取的寬度一般都會(huì)有多位小數(shù)點(diǎn),判斷如果小于0.001的就直接舍掉 const offsetWidth = rangeWidth - Math.floor(rangeWidth); if (offsetWidth < 0.001) { rangeWidth = Math.floor(rangeWidth); } // 獲取元素padding值 const { left, right } = getPadding(dom); const paddingWidth = left + right; // status:文本內(nèi)容是否超出標(biāo)題盒子; // width: 標(biāo)題盒子真實(shí)能夠容納文本內(nèi)容的寬度 return { status: paddingWidth + rangeWidth > dom.clientWidth, width: dom.clientWidth - paddingWidth }; }
通過charCodeAt返回指定位置的字符的Unicode
編碼, 返回的值對(duì)應(yīng)ASCII碼表對(duì)應(yīng)的值,0-127包含了常用的英文、數(shù)字、符號(hào)等,這些都是占一個(gè)字節(jié)長(zhǎng)度的字符,而大于127的為占兩個(gè)字節(jié)長(zhǎng)度的字符。
截取和計(jì)算文本長(zhǎng)度
// 計(jì)算文本長(zhǎng)度,當(dāng)長(zhǎng)度之和大于等于dom元素的寬度后,返回當(dāng)前文字所在的索引,截取時(shí)會(huì)用到。 function calcTextLength(text, width) { let realLength = 0; let index = 0; for (let i = 0; i < text.length; i++) { charCode = text.charCodeAt(i); if (charCode >= 0 && charCode <= 128) { realLength += 1; } else { realLength += 2 * 14; // 14是字體大小 } // 判斷長(zhǎng)度,為true時(shí)終止循環(huán),記錄索引并返回 if (realLength >= width) { index = i; break; } } return index; } // 設(shè)置文本內(nèi)容 function setTextContent(text) { const { status, width } = checkLength(dom); let str = ''; if (status) { // 翻轉(zhuǎn)文本 let reverseStr = text.split('').reverse().join(''); // 計(jì)算左右兩邊文本要截取的字符索引 const leftTextIndex = calcTextLength(text, width); const rightTextIndex = calcTextLength(reverseStr, width); // 將右側(cè)字符先截取,后翻轉(zhuǎn) reverseStr = reverseStr.substring(0, rightTextIndex); reverseStr = reverseStr.split('').reverse().join(''); // 字符拼接 str = `${text.substring(0, leftTextIndex)}...${reverseStr}`; } else { str = text; } dom.innerHTML = str; }
最終實(shí)現(xiàn)的效果如下:
上面就是此功能的所有代碼了,如果想要在本地試驗(yàn)的話,可以在本地新建一個(gè)html文件,復(fù)制上面代碼就可以了。
下面記錄下從社區(qū)內(nèi)學(xué)到的相關(guān)知識(shí):
- js判斷文字被溢出隱藏的幾種方法;
- JS獲取字符串長(zhǎng)度的幾種常用方法,漢字算兩個(gè)字節(jié);
1、 js判斷文字被溢出隱藏的幾種方法
1. Element-plus這個(gè)UI框架中的表格組件實(shí)現(xiàn)的方案。
通過document.createRange
和document.getBoundingClientRect()
這兩個(gè)方法實(shí)現(xiàn)的。也就是我上面代碼中實(shí)現(xiàn)的checkLength
方法。
2. 創(chuàng)建一個(gè)隱藏的div模擬實(shí)際寬度
通過創(chuàng)建一個(gè)不會(huì)在頁(yè)面顯示出來的dom元素,然后把文本內(nèi)容設(shè)置進(jìn)去,真實(shí)的文本長(zhǎng)度與標(biāo)題盒子比較寬度,判斷是否被溢出隱藏了。
function getDomDivWidth(dom) { const elementWidth = dom.clientWidth; const tempElement = document.createElement('div'); const style = window.getComputedStyle(dom, null) const { left, right } = getPadding(dom); // 這里我寫的有點(diǎn)重復(fù)了,可以優(yōu)化 tempElement.style.cssText = ` position: absolute; top: -9999px; left: -9999px; white-space: nowrap; padding-left:${style.paddingLeft}; padding-right:${style.paddingRight}; font-size: ${style.fontSize}; font-family: ${style.fontFamily}; font-weight: ${style.fontWeight}; letter-spacing: ${style.letterSpacing}; `; tempElement.textContent = dom.textContent; document.body.appendChild(tempElement); const obj = { status: tempElement.clientWidth + right + left > elementWidth, width: elementWidth - left - right } document.body.removeChild(tempElement); return obj; }
3. 創(chuàng)建一個(gè)block元素來包裹inline元素
這種方法是在UI框架acro design vue
中實(shí)現(xiàn)的。外層套一個(gè)塊級(jí)(block)元素,內(nèi)部是一個(gè)行內(nèi)(inline)元素。給外層元素設(shè)置溢出隱藏的樣式屬性,不對(duì)內(nèi)層元素做處理,這樣內(nèi)層元素的寬度是不變的。因此,通過獲取內(nèi)層元素的寬度和外層元素的寬度作比較,就可以判斷出文本是否被溢出隱藏了。
// html代碼 <div class="title" id="test"> <span class="content">近日,銀行紛紛下調(diào)大額存單利率,但銀行定期存款仍被瘋搶。銀行理財(cái)經(jīng)理表示:有意向購(gòu)買定期存款要盡快,不確定利率是否會(huì)再降。</span> </div> // 創(chuàng)建一個(gè)block元素來包裹inline元素 const content = document.querySelector('.content'); function getBlockDomWidth(dom) { const { left, right } = getPadding(dom); console.log(dom.clientWidth, content.clientWidth) const obj = { status: dom.clientWidth < content.clientWidth + left + right, width: dom.clientWidth - left - right } return obj; }
4. 使用canvas中的measureText方法和TextMetrics對(duì)象來獲取元素的寬度
通過Canvas 2D渲染上下文(context)可以調(diào)用measureText方法,此方法會(huì)返回TextMetrics對(duì)象,該對(duì)象的width
屬性值就是字符占據(jù)的寬度,由此也能獲取到文本的真實(shí)寬度,此方法有弊端,比如說兼容性,精確度等等。
// 獲取文本長(zhǎng)度 function getTextWidth(text, font = 14) { const canvas = document.createElement("canvas"); const context = canvas.getContext("2d") context.font = font const metrics = context.measureText(text); return metrics.width }
2、JS獲取字符串長(zhǎng)度的幾種常用方法
1. 通過charCodeAt判斷字符編碼
通過charCodeAt獲取指定位置字符的Unicode
編碼,返回的值對(duì)應(yīng)ASCII碼表對(duì)應(yīng)的值,0-127包含了常用的英文、數(shù)字、符號(hào)等,這些都是占一個(gè)字節(jié)長(zhǎng)度的字符,而大于127的為占兩個(gè)字節(jié)長(zhǎng)度的字符。
function calcTextLength(text) { let realLength = 0; for (let i = 0; i < text.length; i++) { charCode = text.charCodeAt(i); if (charCode >= 0 && charCode <= 128) { realLength += 1; } else { realLength += 2; } } return realLength; }
2. 采取將雙字節(jié)字符替換成"aa"的做法,取長(zhǎng)度
function getTextWidth(text) { return text.replace(/[^\x00-\xff]/g,"aa").length; };
到此這篇關(guān)于詳解JS如何實(shí)現(xiàn)文字溢出時(shí)用省略號(hào)...顯示的文章就介紹到這了,更多相關(guān)JS文字溢出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實(shí)現(xiàn)獲取某個(gè)元素相鄰兄弟節(jié)點(diǎn)的prev與next方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)獲取某個(gè)元素相鄰兄弟節(jié)點(diǎn)的prev與next方法,涉及JavaScript基于函數(shù)的判定及調(diào)用previousSibling與nextSibling的相關(guān)技巧,需要的朋友可以參考下2016-01-01javascript跨域請(qǐng)求包裝函數(shù)與用法示例
這篇文章主要介紹了javascript跨域請(qǐng)求包裝函數(shù)與用法,結(jié)合實(shí)例形式分析了javascript基于ajax的跨域請(qǐng)求封裝函數(shù)與相關(guān)使用技巧,需要的朋友可以參考下2016-11-11原生javascript的ajax請(qǐng)求及后臺(tái)PHP響應(yīng)操作示例
這篇文章主要介紹了原生javascript的ajax請(qǐng)求及后臺(tái)PHP響應(yīng)操作,結(jié)合示例形式分析了JavaScript前臺(tái)ajax請(qǐng)求的原理、調(diào)用、后臺(tái)PHP響應(yīng)請(qǐng)求及cookie保存相關(guān)操作技巧,需要的朋友可以參考下2020-02-02JavaScript雙向鏈表實(shí)現(xiàn)LFU緩存算法
本文主要介紹了JavaScript雙向鏈表實(shí)現(xiàn)LFU緩存算法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01Vue2.0+ElementUI實(shí)現(xiàn)表格翻頁(yè)的實(shí)例
下面小編就為大家?guī)硪黄猇ue2.0+ElementUI實(shí)現(xiàn)表格翻頁(yè)的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10基于JS實(shí)現(xiàn)點(diǎn)擊圖片在彈出層顯示大圖效果
Javascript是個(gè)好東西。Jquery是基于這個(gè)好東西的一個(gè)強(qiáng)大的庫(kù)。本文將利用JavaScript實(shí)現(xiàn)點(diǎn)擊圖片在彈出層顯示大圖功能,感興趣的可以了解一下2022-08-08js實(shí)現(xiàn)轉(zhuǎn)盤抽獎(jiǎng)功能
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)轉(zhuǎn)盤抽獎(jiǎng)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03ECharts數(shù)據(jù)可視化基本使用之常用圖表類型
這篇文章主要給大家介紹了關(guān)于ECharts數(shù)據(jù)可視化基本使用之常用圖表類型的相關(guān)資料,echarts是一款基于JavaScript的數(shù)據(jù)可視化圖表庫(kù),提供直觀,生動(dòng),可交互,可個(gè)性化定制的數(shù)據(jù)可視化圖表,需要的朋友可以參考下2023-11-11