# 前言
这是去年在校做项目遇到的一个需求,文章沉在草稿箱里一直没写完,主要分享一下如何实现长文本的折叠展开。
长文本超过限定行数自动折叠,点击长文本或者按钮,实现展开收起效果。这类效果其实在平时的app中或者网站中很常见,举几个栗子:
微信朋友圈:
新浪微博:
# 分析需求
# 1、文本超长省略,主要是通过 line-clamp 实现:
.text-clamp2 {
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
文本效果:
# 2、如何判断文本是否超出两行,显示「全文」「收起」按钮呢?
通过上图我们可以发现,当文本区域省略时,它的高度会相对变小,那么我们只需要获取到不省略和省略时的文本区域高度,进行比较就能知道是否超出了两行。
思路解决了,怀着喜悦的心情翻看了一下文档:咦?为什么小程序没有像 js 那样操作 dom 节点的接口?那还怎么获取元素的尺寸高度!好在功夫不负有心人,终于在文档找到类 DOM 操作的 API「SelectQuery (opens new window)」。
# 实现需求
# 3、什么是 SelectQuery?如何去使用它?
从文档(传送门) (opens new window)描述来看 SelectQuery 是一个查询节点信息的对象,它可以选择匹配选择器的所有节点以及显示区域内的节点信息。既然它可以类似 jQuery 那样去匹配选择器,那么我们可以获取到需要的高度信息了。
// wxml
<view class="contentInner1 text-clamp2">小程序是一种新的开放能力,开发者可以快速地开发一个小程序。小程序可以在微信内被便捷地获取和传播,同时具有出色的使用体验。</view>
<view class="contentInner2">小程序是一种新的开放能力,开发者可以快速地开发一个小程序。小程序可以在微信内被便捷地获取和传播,同时具有出色的使用体验。</view>
// js
wx.createSelectorQuery().selectAll(".contentInner1, .contentInner2").boundingClientRect(res => {
console.log(res)
}).exec()
查询结果(文本区域省略时高度为 52px、不省略时为 104px,只要 res[0].height < res[1].height,此时就应该显示展开收起按钮 )
# 4、逻辑设计上的优化
由于论坛帖子不只一个,我们得匹配对应的两个长文本节点,如果都给一个唯一的选择器,那么在页面中一次性查询这么多节点,很明显这不是最优的。
实际上我们可以将这封装成一个自定义组件 (opens new window),可供每个页面循环复用,在组件内我们只需要关注 单个 长文本的节点信息,不需要一次性获取当前页面的所有长文本节点,更重要的是:在组件内每个长文本的展开与收起状态都是独立的,也省去了在页面内定义字段去标识每个帖子的展开状态。
# 5、实现效果
# 6、参数说明
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
content | String | "示例文本" | 长文本内容 |
maxline | Number | 1 | 最多展示行数[只允许 1-5 的正整数] |
position | String | "left" | 展开收起按钮位置[可选值为 left right] |
foldable | Boolean | true | 点击长文本是否展开收起 |