背景
入職頭條快一年姑原,平常工作中悬而,不止一次聽到 UI 反饋,頭條 App 內(nèi)的 h5 上偶爾會出現(xiàn)下面這樣的體驗 bug锭汛。
在縮略符 “...” 前面會小概率出現(xiàn)標(biāo)點符號笨奠,看起來很不雅觀。這么長時間這個問題一直沒解決唤殴,因為自己手頭的業(yè)務(wù)有點多也就沒去關(guān)注這個他人需求般婆。
最近剛好弄完績效評估處于需求真空期,剛好想起這個問題眨八,就順手給解決了腺兴,沉淀了個 react 的縮略組件左电×啵考慮到這是個很通用的需求,所以整理了一下開源出來篓足。
先直接上干貨吧段誊,組件已經(jīng)開源在 github 上,倉庫地址: react-ellipsis (覺得有用可以給個 star)栈拖。
可能會有人疑惑连舍,這么常見的需求真的沒有可用的輪子嗎?我一開始也帶著這個疑惑涩哟,搜了一下 npm 和 github索赏,發(fā)現(xiàn)還真沒有能完全符合條件的...
那就自己來造一個吧 -。-
造輪子前
在準(zhǔn)備動手解決問題前贴彼,我瀏覽了一下 npm 和 github 上已有的縮略組件潜腻,根據(jù) star 數(shù)挑幾個看看
react-lines-ellipsis
截止發(fā)文
- stars 數(shù) 376
- 未處理 issue 15
- 上次功能更新 2 年前
問題:
不支持結(jié)尾標(biāo)點符號過濾,只能過濾空白符(可通過 pr 解決器仗,但是作者很長時間未處理 pr 了)
-
每個 ellipsis 組件都會生成一個隱藏的 div 去計算融涣,性能損耗嚴(yán)重
image 不支持設(shè)置高度縮略
react-truncate
截止發(fā)文
- stars 數(shù) 503
- 未處理 issue 33
- 上次功能更新 8 月前
問題:
- 不支持結(jié)尾標(biāo)點符號過濾童番,只能過濾空白符
- 不支持按單詞或字母切割
- onResize 需要自行調(diào)用
- 使用 canvas 實現(xiàn),當(dāng)元素較多時性能損耗嚴(yán)重
其他組件或多或少都有各自的問題導(dǎo)致無法滿足我們的需求威鹿,所以動手自己擼吧剃斧。
輪子介紹
吭哧吭哧搞了一個下午就寫完了,目前迭代到 0.5.2 版本忽你。
先看個簡單的示例
提示:容器拉伸是為了方便演示加的幼东,實際組件不包含拉伸功能。
已經(jīng)實現(xiàn)和計劃中的功能:
已完成功能
- 自定義縮略符
- 自定義縮略符節(jié)點
- 尾字符過濾
- 縮略回調(diào)
- 縮略符點擊回調(diào)
- 自適應(yīng)
計劃中
- 按單詞或字母分割
- 支持內(nèi)容換行
- 支持收起符
- ResizeObserver 不支持時用 window.onresize 兼容
具體功能和示例可以查看 react-ellipsis 文檔
Q & A
-
如何保障性能檀夹?
切割算法上筋粗,其他組件大多是通過切割成字符數(shù)組后,一個個減少直到容器不再溢出炸渡,時間復(fù)雜度是 O(n)娜亿。react-ellipsis-component 使用二分切割將時間復(fù)雜度降到 O(logn)。
計算時在原容器上計算蚌堵,其他組件使用隱藏的 div 或者 canvas买决,當(dāng) ellipsis 組件很多時性能損耗嚴(yán)重。
在自適應(yīng)上吼畏,使用 ResizeObserver 實現(xiàn)督赤,而其他組件使用 window.onresize(性能損耗比較大)。
-
兼容性
兼容性主要在于 ResizeObserver 實現(xiàn)的自適應(yīng)縮略泻蚊,如果不需要自適應(yīng)縮略躲舌,可以覆蓋絕大部分的現(xiàn)代瀏覽器。組件本身除了 react 不依賴其他庫性雄,兼容性有保證没卸。
后續(xù)會添加 window.onresize 的兼容邏輯進(jìn)一步提高兼容性。
附:ResizeObserver 兼容性表
image