之前做小程序開發(fā)時(shí),遇到要實(shí)現(xiàn)過長文本進(jìn)行的折疊的效果(類型微信朋友圈的效果)。主要交互有三點(diǎn):
本質(zhì)上,要實(shí)現(xiàn)這個(gè)效果得解決兩個(gè)問題:
如何判斷文本是否過長?
所謂「文本過長」,就是文本占據(jù)屏幕的高度太大。之所以要判斷這個(gè),是為了能告知邏輯層控制「全文」按鈕的展示與切換。如果沒這個(gè)交互,完全可忽略這個(gè)問題。
最直接的文本過長判斷標(biāo)準(zhǔn),是文本行數(shù)超過某個(gè)值。在瀏覽器端,可通過 DOM 獲取容器高度和文本的行高,來計(jì)算文本顯示的行數(shù)。
但小程序中,并沒有給 JS 訪問文本行數(shù)或組件高度的接口。我們無法從視圖層獲知行數(shù)過多的信息,并告知邏輯層。
所以,我們只能退而求其次,采用字符數(shù)來作為文本過長的標(biāo)準(zhǔn)。至于多少字符算過長,可綜合容器寬度、字符(中文字符會(huì)占兩個(gè)英文字符寬度)、字體、字號,和設(shè)計(jì)師確認(rèn)。
但顯然這種做法還有問題。比如,遇到每行字符數(shù)很少卻會(huì)顯示許多行的情況(例如回車過多),系統(tǒng)就不會(huì)進(jìn)行文本過長的處理,違背我們折疊過長文本的初衷。
文本過長時(shí),如何折疊?
一個(gè)簡單的思路是用行高算出一個(gè)固定的高度,只顯示前幾行,但該做法過于依賴樣式的實(shí)現(xiàn)、不利于維護(hù)。
在小程序中,我們可采用移動(dòng)端頁面開發(fā)中一個(gè) hack 技術(shù): -webkit-line-clamp 。這個(gè) Webkit 內(nèi)核私有的 CSS 屬性,用于設(shè)置留在容器中的文本行數(shù),讓其余的文本處于「溢出」?fàn)顟B(tài)。
接下來,只要結(jié)合 text-overflow: ellipsis; 和 overflow: hidden; ,就能達(dá)到讓過長的文本只顯示前幾行的效果,即「折疊」效果。
-webkit-line-clamp 的使用,有幾個(gè)需要注意的點(diǎn)。
首先是兼容性。其在 Chrome、Safari、QQ 等 Webkit 系瀏覽器都很可靠。而微信小程序的 View 渲染引擎 WKWebView 和 X5 也都是從 Webkit 改過來的,兼容性有較好的保障。
另外,該屬性有個(gè)使用前提:需在文本容器開啟 Webkit 瀏覽器私有的 Flex 布局: display: webkit-box; ,并將設(shè)置子元素的排列方式為 -webkit-box-orient: vertical; 。
同時(shí),該屬性對行數(shù)的計(jì)算是依據(jù) inline 元素來的,只會(huì)計(jì)算 inline 元素的行數(shù)。
基于第三點(diǎn),在涉及到文本分段時(shí),為了實(shí)現(xiàn)按指定的行數(shù)折疊,就不能把每段輸出到一個(gè) block 元素(比如 view 組件)中了。那要怎么分段呢?
雖然小程序沒有
這種東西,但好在其 text 組件支持轉(zhuǎn)義字符。我們可以把每段輸?shù)揭粋€(gè) text 組件中,并在 text 組件結(jié)尾加上 \n 來實(shí)現(xiàn)分段。
總結(jié)
以上,總結(jié)下小程序下文本過長折疊的思路:文本過長由邏輯層判斷字符數(shù)確定,控制「全文」按鈕的展示與切換。過長時(shí)應(yīng)用 -webkit-line-clamp 樣式折疊文本,再次展開文本只要撤銷該樣式。
工作日 8:30-12:00 14:30-18:00
周六及部分節(jié)假日提供值班服務(wù)