# 前言

这是去年在校做项目遇到的一个需求,文章沉在草稿箱里一直没写完,主要分享一下如何实现长文本的折叠展开。

长文本超过限定行数自动折叠,点击长文本或者按钮,实现展开收起效果。这类效果其实在平时的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 点击长文本是否展开收起

# 最后附上代码片段 (opens new window),有疑问欢迎发社区私信 (opens new window)(三连暗示)