淺談移動端過長文本溢出顯示省略號的實現方案

本文首發於 vivo互聯網技術 微信公衆號 
鏈接: https://mp.weixin.qq.com/s/39NCyZvm8EYiJ-pEEtjxGw
作者:何彥軍

目前在移動端開發的展示界面中,如果一段文本的數量過長,受限於屏幕的寬高等因素,有可能不能完全顯示,這個時候就會把溢出的文本顯示成省略號。

最近就親身經歷了一系列類似的需求,於是這裏做個總結和記錄。

首先一個最基本的需求就是當文本超過一行最大寬度時,超出的部分變爲省略號,如下圖所示。

淺談移動端過長文本溢出顯示省略號的實現方案

這個功能比較基礎,只用css就可以實現,如下圖所示代碼塊。

淺談移動端過長文本溢出顯示省略號的實現方案

可是有時候產品同學希望顯示的文本可以再多一點,於是就有了多行文本溢出顯示省略號的需求,如下圖所示。

淺談移動端過長文本溢出顯示省略號的實現方案淺談移動端過長文本溢出顯示省略號的實現方案

這個功能也可以通過css實現,如下圖代碼塊所示。

淺談移動端過長文本溢出顯示省略號的實現方案淺談移動端過長文本溢出顯示省略號的實現方案

這裏用到了webkit的css擴展屬性,因此適用於webkit瀏覽器及移動端,並且在兼容性方面也有些影響,但是隻要不是特別老舊的機器,還是完全能夠支持的。

在支持了多行文本溢出顯示省略號的功能之後,產品同學又發現了體驗不友好的點,如下圖所示。文本在第二行開頭處就結束了,這就導致第二行大部分是空白的,影響了美觀度。

淺談移動端過長文本溢出顯示省略號的實現方案

因此,產品同學提出了一個新需求:

  • 當文本沒有超過第x行的一半時,則按第x-1行溢出顯示省略號的方式展示;(第1行除外)

  • 當文本超過第x行的一半但沒有超過第x行時,則正常展示;

  • 當文本超過第x行時,則按第x行溢出顯示省略號的方式展示。

這就需要計算出文本實際佔用的寬度才能選擇採用哪種展示方式。

查找資料得知,canvas提供了一個measureText的方法,該方法的返回包含一個對象,這個對象裏包含了以像素計的指定字體寬度。

如果需要在文本顯示之前,就瞭解文本的寬度,那麼可以使用該方法。

淺談移動端過長文本溢出顯示省略號的實現方案

上面的代碼顯示效果如下:

淺談移動端過長文本溢出顯示省略號的實現方案

於是可以基於canvas能力來實現這個功能,大概的流程圖如下圖所示。

淺談移動端過長文本溢出顯示省略號的實現方案淺談移動端過長文本溢出顯示省略號的實現方案

這裏最關鍵的是要計算出每一行可以顯示多少文本,利用canvas的measureText方法,可以達到這個效果,僞代碼如下所示。

淺談移動端過長文本溢出顯示省略號的實現方案淺談移動端過長文本溢出顯示省略號的實現方案

雖然canvas可以計算出文本顯示的寬度,並且兼容性和性能都還不錯,但是當某一行末尾出現特殊符號或者是英文單詞時,就會出現預期外的情況。

瀏覽器實際渲染出來的時候,如果末尾有特殊符號時會連同前面的字符一起換行,而如果末尾有英文單詞時也會將這個英文單詞換行展示。

但通過canvas計算出來的結果,會導致每一行的文本增多了,從而跟預期的展示效果有出入。

因此,這種方案只能適用於文本中不包含特殊符號和英文單詞的場景。

一段時間後,產品同學感覺展示那麼一段文本有點兒單調,於是又提出了一個進階版的需求:

  • 文本的首行開頭需要縮進或者可以配置一個圖標;

  • 文本的末尾可以配置按鈕或者圖標,並且如果文本超過了範圍需要顯示省略號,但是省略號需要在按鈕或圖標的前面。

順帶給出了一個參考示例,如下圖所示。

淺談移動端過長文本溢出顯示省略號的實現方案

由於之前沒有遇到過類似的需求,於是開始google這個問題,經過海量的檢索,終於發現了該問題實現的方案。

原來網上也有很多朋友遇到了這樣的需求,並專門寫了單獨的組件來使用,比如:

HeyUI:https://www.heyui.top/component/other/textellipsis

vue-text-ellipsis:https://github.com/Luobata/vue-text-ellipsis

它們的思路都是通過最終展示的實際高度是否超過預期的容器高度來判斷是否需要刪減文本。其流程圖大概如下圖所示。

淺談移動端過長文本溢出顯示省略號的實現方案

就這樣,通過現成的組件就解決了一個難題。

然鵝,本以爲需求已經告一段落了,哪知產品同學又開始了體驗上的深度挖掘。

她們認爲,展示的文本樣式不應該都是一樣的。

有些文本表達的意思可能比較重要,這就需要重點引起用戶的注意。

而有些文本表達的意思可能重要程度一般,這就不需要用戶注意。

於是乎她們又提出了一個通過高亮文本來提升用戶體驗的需求:

  • 能夠根據文本的標記進行高亮展示

比方說,獲取到下面一段文本,它要顯示出入下圖所示的那樣高亮效果。

淺談移動端過長文本溢出顯示省略號的實現方案淺談移動端過長文本溢出顯示省略號的實現方案

淺談移動端過長文本溢出顯示省略號的實現方案淺談移動端過長文本溢出顯示省略號的實現方案

由於文本高亮需要通過標籤將文本包裹起來並添加高亮樣式才能實現,而之前的組件是通過v-text的方式實現的,因此這裏不能直接使用,需要將組件改造成v-html的方式插入纔可以。

假如通過v-html插入文本,並且設置了em標籤的樣式,那麼就會有一個問題,組件是通過循環剔除最後一個字符直到實際高度小於容器高度來實現展示功能的,這就有可能截掉標籤字符,導致最後的展示有異常。

所以,在截取文本的時候還需要做一些處理,流程圖如下圖所示。

淺談移動端過長文本溢出顯示省略號的實現方案

到這裏,已經實現文本的一種高亮形式了,但是假如有好幾個部分的文本需要高亮且高亮的樣式還各不相同,這又要怎麼解決呢?

一種思路是,通過幾種不同名稱的標籤分別包裹需要高亮的文本,每一種標籤會對應一種高亮樣式,這樣的話,在獲得源文本後,首先通過詞法分析將源文本中的標籤解析出來,後面的流程就跟上圖步驟1後面的流程類似了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章