Vue3中文本只顯示三行晰绎,超過部分在文字后顯示省略號和展開按鍵

看著簡單實則小麻煩的一個功能

1. 參考文章

2. 實現(xiàn)效果

超過三行時,在文字后方顯示省略號和展開按鍵


段落收起

點擊展開按鍵辛慰,顯示全部內容


段落展開

3. 代碼

  • HTML代碼
  <div class="hello">
    <div class="detailed-introduce">
      <div
        class="intro-content"
        ref="content"
      >
        <span
          class="merchant-desc"
          v-if="introduce"
          ref="desc"
        >
          {{introduce}}
        </span>
        <div
          class="unfold"
          @click="clickTotal"
          v-if="showExchangeButton"
        >
          {{showTotal ? '收起' : '展開'}}
        </div>
      </div>
    </div>
  </div>

  • CSS代碼(Scss)
.detailed-introduce {
  width: 800px;
  border: 2px solid grey;
  padding: 10px;
  margin: 0 auto;

  font-size: 14px;
  color: #627081;
  position: relative;
  overflow: hidden;

  .intro-content {
    // 最大高度設為3倍的行間距
    text-indent: 15px;
    overflow: hidden;
    text-align: left;

    .merchant-desc {
      width: 100%;
      line-height: 20px;
    }

    .unfold {
      text-indent: 0;
      z-index: 11;
      height: 20px;
      position: absolute;
      right: 15px;
      bottom: 10px;
      background: #f5f6f7;
      opacity: 1;
      cursor: pointer;
      color: #2878ff;
    }
  }
}


  • JS代碼
import { onMounted, reactive, toRefs, ref, nextTick } from 'vue'
export default {
  setup () {
    const state = reactive({
      showTotal: false, // 是否展示所有文本內容
      showExchangeButton: false, // 是否顯示展開收起按鈕
      showLine: 3 // 顯示的文本行數(shù)
    })

    const introduce = ref(' ') // 初始化文本
    const desc = ref(null) // 文本組件

    onMounted(() => {
      // 獲取初始化數(shù)據(jù)
      loadInfo()
    })

    /** 文本的操作方法 */
    const txtMethods = {
      /** 將HTML文本轉化為文字文本 */
      toText: (HTML) => {
        var input = HTML
        return input.replace(/<(style|script|iframe)[^>]*?>[\s\S]+?<\/\1\s*>/gi, '').replace(/<[^>]+?>/g, '').replace(/\s+/g, ' ').replace(/ /g, ' ').replace(/>/g, ' ')
      },

      /** 截取三行文本 */
      txtDec: () => {
        if (!desc.value) {
          return
        }
        if (introduce.value) { // 對頁面中的元素重新賦值区匠,否則會采用之前裁剪過的文本
          desc.value.innerHTML = introduce.value
        } else {
          return
        }

        nextTick(() => {
          let rows = desc.value.getClientRects().length // 文本行數(shù)
          let txt = introduce.value // 文本
          // 文本為3行時的字數(shù)長度
          let tl = 0 // eslint-disable-line no-unused-vars
          if (rows < state.showLine) { // 未超出行數(shù),返回
            desc.value.innerHTML = introduce.value
            state.seriesInfo.introduction.length - introduce.value.length > 10 ? state.showExchangeButton = true : state.showExchangeButton = false // html元素大于30個字符,顯示展開按鈕
            return
          }

          // 數(shù)據(jù)量大時速度太慢驰弄,需優(yōu)化(二分法麻汰?)
          while (rows > state.showLine) { // 超出,遍歷文字并進行截取戚篙,直到文本小于三行
            let step = 1 // 末尾扣除的字數(shù)
            if (/<br\/>$/.test(txt)) { // 回退的時候五鲫,如果碰到換行要整體替換
              step = 5
            }
            txt = txt.slice(0, -step) // 截取
            desc.value.innerHTML = txt
            rows = desc.value.getClientRects().length
            tl += step
          }
          if (txt.charCodeAt(txt.length - 1) < 255) { // 文字末尾留三個字符的空并加省略號(中文字符和英文字符留空大小不同,中文-3岔擂,英文-8)
            desc.value.innerHTML = txt.slice(0, -8) + '...'
          } else {
            desc.value.innerHTML = txt.slice(0, -3) + '...'
          }
          state.showExchangeButton = true // 顯示展開收起按鈕
          state.exchangeButton = true
        })
      }
    }

    /** 防抖函數(shù) */
    const debounce = (fn, wait) => {
      let timer2 = null
      return function () {
        if (timer2 !== null) {
          clearTimeout(timer2)
        }
        timer2 = setTimeout(fn, wait)
      }
    }

    /** 點擊展開/收起按鈕 */
    const clickTotal = () => {
      state.showTotal = !state.showTotal
      // 頁面數(shù)據(jù)過多時txtDec的循環(huán)塊會運行一段時間位喂,造成點擊“收起”按鈕時卡頓
      // 解決方法:在收起時為父元素增加max-height樣式,達到隱藏效果
      // 解決失斅伊椤:初步判斷是vue的虛擬dom算法塑崖,不能立即更新元素樣式,等到nextTick后才會更新
      !state.showTotal ? desc.value.parentNode.style['max-height'] = `${20 * state.showLine}px` : desc.value.parentNode.style['max-height'] = ''
      state.showTotal ? desc.value.innerHTML = introduce.value : txtMethods.txtDec()
    }

    /** 窗口尺寸改變時重新計算文本的顯示長度:使用防抖函數(shù)實現(xiàn) */
    window.addEventListener('resize', debounce(txtMethods.txtDec, 200))

    /** 數(shù)據(jù)初始化 */
    const loadInfo = () => {
      // 使用封裝的api從后臺接口獲取描述信息(使用自己的接口地址)
      introduce.value = `從倉頡造字的古老傳說到公元前1000多年前甲骨文的發(fā)現(xiàn)阔蛉,歷代中國學者一直致力于揭開漢字起源之謎弃舒。關于漢字起源的說法癞埠,歷來各家有不同主張状原,其中比較有影響力的說法有:結繩說、八卦說苗踪、刻契說颠区、倉頡造字說、刻劃說和圖畫說通铲。
      結繩說:在文字產生之前毕莱,古人們靠結繩記事、認事颅夺,此舉起到了幫助人們記憶的作用朋截。《周易·系辭下》:“上古結繩而治吧黄,后世圣人易之以書契部服,百官以治,萬民以察拗慨±耍”漢代鄭玄注:“結繩為約,事大赵抢,大結其繩剧蹂;事小,小結其繩烦却〕璧穑”《莊子·胠篋》篇云:“昔者容成氏、大庭氏其爵、伯皇氏车吹、中央氏筹裕、栗陸氏梦谜、驪畜氏澜薄、軒轅氏、赫胥氏香椎、尊盧氏乐埠、祝融氏抗斤、伏羲氏、神農氏丈咐,當是時也瑞眼,民結繩而用之】醚罚”又如《周易正義》引《虞鄭九家義》: “古者無文字伤疙,其有約誓之事,事大大結其繩辆影,事小小結其繩徒像。結之多少,隨物眾寡蛙讥;各執(zhí)以相考锯蛀,亦足以相治也〈温”東漢以后旁涤,不少人把漢字起源附會于結繩[5]  。
      八卦說:關于八卦的起源說法并不統(tǒng)一迫像,有摹象說劈愚、星象說、數(shù)說和楊雄的“亥”為物之源說等等闻妓【穑《周易·系辭》云:“古者庖犧氏之王天下也,仰則觀象于天纷闺,俯則觀法于地算凿,觀鳥獸之文與地之宜,近取諸身犁功,遠取諸物氓轰,于是始作八卦,以通神明之德浸卦,以類萬物之情署鸡。”這段話提到八卦源自庖犧氏對自然客觀世界的摹象,這與“依類象形”而作的漢字的起源是相似的靴庆∈卑疲孔安國《尚書》序(屬偽作,但年代甚古)里說:“古者庖犧氏之王天下也炉抒,始畫八卦奢讨,造書契,以代結繩之政焰薄,由是文籍生焉拿诸。”把八卦和書契(文字)的作用相提并論塞茅,把漢字的起源與八卦聯(lián)系起來[5]  亩码。
      倉頡造字說:相傳倉頡是黃帝時期的史官,漢字的創(chuàng)造者[6]  野瘦。黃帝是古代中原部落聯(lián)盟的領袖描沟,由于社會進入較大規(guī)模的部落聯(lián)盟階段,聯(lián)盟之間外交事務日益頻繁鞭光,故迫切需要建立一套各盟聯(lián)共享的交際符號吏廉,于是搜集及整理共享文字的工作便交在史官倉頡的手上了。`
      txtMethods.txtDec()
    }

    return {
      ...toRefs(state),
      introduce,
      desc,
      clickTotal
    }
  }
}

3. 總結

主要是使用getClientRects().length方法獲取文本的行數(shù)衰猛,判斷文本顯示是否超過3行迟蜜,大于3行時進行截取并重新給元素賦值刹孔。
頁面寬度變化時需要重新進行計算啡省。

4. github

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市髓霞,隨后出現(xiàn)的幾起案子卦睹,更是在濱河造成了極大的恐慌,老刑警劉巖方库,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件结序,死亡現(xiàn)場離奇詭異,居然都是意外死亡纵潦,警方通過查閱死者的電腦和手機徐鹤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邀层,“玉大人返敬,你說我怎么就攤上這事×仍海” “怎么了劲赠?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我凛澎,道長霹肝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任塑煎,我火速辦了婚禮沫换,結果婚禮上,老公的妹妹穿的比我還像新娘最铁。我一直安慰自己苗沧,他們只是感情好,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布炭晒。 她就那樣靜靜地躺著待逞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪网严。 梳的紋絲不亂的頭發(fā)上识樱,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機與錄音震束,去河邊找鬼怜庸。 笑死,一個胖子當著我的面吹牛垢村,可吹牛的內容都是我干的割疾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼嘉栓,長吁一口氣:“原來是場噩夢啊……” “哼宏榕!你這毒婦竟也來了?” 一聲冷哼從身側響起侵佃,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤麻昼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后馋辈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抚芦,經...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年迈螟,在試婚紗的時候發(fā)現(xiàn)自己被綠了叉抡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡答毫,死狀恐怖褥民,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情烙常,我是刑警寧澤轴捎,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布鹤盒,位于F島的核電站,受9級特大地震影響侦副,放射性物質發(fā)生泄漏侦锯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一秦驯、第九天 我趴在偏房一處隱蔽的房頂上張望尺碰。 院中可真熱鬧,春花似錦译隘、人聲如沸亲桥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽题篷。三九已至,卻和暖如春厅目,著一層夾襖步出監(jiān)牢的瞬間番枚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工损敷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留葫笼,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓拗馒,卻偏偏與公主長得像路星,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子诱桂,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內容

  • 目錄 如何遍歷數(shù)組 如何遍歷對象 http瀏覽器緩存機制 304狀態(tài)碼 500狀態(tài)碼具體場景 DNS原理 CND原...
    Grandperhaps閱讀 329評論 0 1
  • 概率與統(tǒng)計 概率是已知模型洋丐、參數(shù)推數(shù)據(jù),而統(tǒng)計是已知數(shù)據(jù)推模型和參數(shù)访诱。似然和概率是兩個意思很相似的詞垫挨,但含義不同韩肝。...
    陳城南閱讀 1,128評論 0 1
  • 收集LaTeX寫作中自己常遇到的問題的解決方法触菜,希望對大家有幫助~ 1 字符公式 1-1、如何編輯大小羅馬數(shù)字[h...
    三金姐姐閱讀 271評論 0 3
  • 讀到一段話 A Simple regression model is one that attempts to f...
    曲涼不見閱讀 1,620評論 0 0
  • 在使用vue-cli 3.0的版本中會發(fā)現(xiàn)跟vue-cli2.0的差別很大哀峻,一開始打開項目會發(fā)現(xiàn)居然沒有build...
    越來越_8c59閱讀 608評論 0 0