判斷文本是否溢出
問題
需求:當(dāng)一個(gè)div的內(nèi)容過多時(shí),顯示省略號,并提供一個(gè)顯示更多的按鈕;如果內(nèi)容較少,正常展示不提供按鈕。
分析:以上問題的本質(zhì)就在于,如何判斷div的內(nèi)容溢出了
(為了方便,方案采用vue的寫法)
方案一
方案一為Determine if an HTML element's content overflows中的最高贊回答,主要思想是對比元素的el.clientWidth和el.scrollWidth,如果scrollWidth較大,說明溢出了,否則沒溢出。?
? <div class='content' ref="content">長長的內(nèi)容長長的內(nèi)容</div>????<button?v-if="showBtn">顯示</button>
?
const el = this.$refs.contentthis.showBtn = el.clientWidth < el.scrollWidthwindow.addEventListener('resize', () => {this.showTest = el.clientWidth < el.scrollWidth????})
.test{width:10%;background: #ccc;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}
為了測試方便,以上demo加上了改變窗口大小的resize函數(shù),可以發(fā)現(xiàn)div寬度增大時(shí),文本不溢出不顯示按鈕,div寬度縮小時(shí),文本溢出顯示按鈕
stackoverflow的回答下,有人反映此方案在某些瀏覽器會出現(xiàn),文本溢出了,但clientWidth與scrollWidth相等。于是有人提到了另一個(gè)方案
方案二
方案二位?HTML text-overflow ellipsis detection的最高贊回答,主要是將div克隆一份但不顯示(visibility:hidden),比較兩者的寬度,如果副本的寬度大于元素本身的寬度,則表示溢出,否則未溢出
?<div class='content' ref="content">長長的內(nèi)容長長的內(nèi)容</div><div class='content-copy' ref="contentCopy">長長的內(nèi)容長長的內(nèi)容</div><button v-if="showBtn">顯示</button>
const el = this.$refs.contentconst elCopy = this.$refs.contentCopythis.showBtn = el.clientWidth < elCopy.clientWidthconsole.log(el.clientWidth, elCopy.clientWidth)window.addEventListener('resize', () => {this.showBtn = el.clientWidth < elCopy.clientWidth????})
.content{display: inline-block;width:10%;background: #ccc;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}.content-copy{display: inline-block;visibility: hidden;??}
這里要注意一點(diǎn),此方案中元素不能為block,因?yàn)檫@樣eleCopy的寬度會為父元素的100%,而不是由內(nèi)容撐開的寬度;也不能為inline,因?yàn)檫@樣沒有width,無法比較;因此將元素設(shè)為inline-block
應(yīng)用場景
在列表中,會經(jīng)常出現(xiàn)這種溢出的情況。比如我遇到的問題:在列表的某一行文字發(fā)生溢出時(shí),hover才展示提示。
通過設(shè)置一個(gè)變量,在觸發(fā)當(dāng)前mouserenter事件時(shí),動(dòng)態(tài)計(jì)算是否展示提示
const<div?className="list"><Tooltip title={isOverflow ? '測試測試測試' : ''}><spanonmouseEnter={(e) => {const target = e.target as HTMLElement;setIsOverflow(target.scrollWidth - target.clientWidth > 0);}}>測試測試測試<span></Tooltip><Tooltip title={isOverflow ? '測試測試測試' : ''}><spanonmouseEnter={(e) => {const target = e.target as HTMLElement;setIsOverflow(target.scrollWidth - target.clientWidth > 0);}}>測試測試測試<span></Tooltip></div>
小結(jié)
以上2種方案都可以實(shí)現(xiàn)判斷文本是否溢出,雖然思想有所不同,但其實(shí)本質(zhì)是一樣的:都是通過對比文本實(shí)際的寬度和顯示省略號時(shí)的寬度,所以可以從這一點(diǎn)出發(fā),再多多思考有沒有其他解決方案。
