### [聊聊小程序怎么实现“全文收起”功能](https://www.prosaas.cn/article/16293) **Published:** 2022-03-07T11:45:28 **Author:** 5201314 **Excerpt:** 小程序怎么实现“全文收起”功能?下面本篇文章小程序实现多行文本“全文收起”功能的方法,希望对大家有所帮助!小程… 小程序怎么实现“全文收起”功能?下面本篇文章小程序实现多行文本“全文收起”功能的方法,希望对大家有所帮助! ![](https://img.php.cn/upload/article/000/000/024/6225f031a3521631.jpg) 小程序里经常会碰到需要实现多行文本”全文收起“功能,在掘金上有搜索到用**纯css实现**。亲测:**ios很完美,andriod上的无效**。 小程序社区有很多方案,目前在社区有看到一位大佬使用**js动态计算**告诉去实现,亲测大致有效果,测试后,在一些特殊情况下,计算会有误差,所以有更改些许代码。 ## 一、需求 - 位于多行文本右下角,展示”全文/收起“按钮 - “展开”和“收起”两种状态的切换 - 当文本不超过指定行数时,不显示”全文/收起“按钮 - 文本显示【全文】展示状态下,更新数据,文本不被收起 ## 二、实现思路 ### **1、多行文本截断** 主要用到用到 **line-clamp**,关键样式如下 .text-clamp3 { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; } ### **2、判断文本是否超出指定行数,显示全文 收起 按钮** 编写两段文本,一段展示完整的文本A,一段展示使用 **line-clamp**省略后的文本B,因为B有被截取,因此B的高度相对较小。对比两段文本的高度,便可以知道文本是否超出两行 在小程序里,可以使用`wx.createSelectorQuery()`获取文本高度 js const query = wx.createSelectorQuery().in(this); query.selectAll(".showArea, .hideArea").boundingClientRect(res => { console.log(res, 'res') }).exec() ![](https://img.php.cn/upload/image/696/435/769/1646653285663937.png) ## 三、代码实现 ### **1、初次版本** 根据设计思路,立马上手代码 **foldable.wxml** {{content}} {{content}} {{onFold ? unFoldText : onFoldText}} **foldable.js** /\*\* \* 长文本内容展开与收起 \* @param {String} content 长文本内容 \* @param {Number} maxLine 最多展示行数\[只允许 1-5 的正整数\] \* @param {String} position 展开收起按钮位置\[可选值为 left right\] \* @param {Boolean} foldable 点击长文本是否展开收起 \* @param { String } onFoldText 收缩时文字 \* @param { String } unFoldText 展开时文字 \* \*/ Component({ externalClasses: \['content-inner-class', 'fold-class'\], properties: { content: { type: String, observer(val) { if (this.data.onReady) { this.getNodeClientReact() } } }, maxLine: { type: Number, value: 1, observer(value) { if (!(/^\[1-5\]$/).test(value)) { throw new Error(\`maxLine field value can only be digits (1-5), Error value: ${value}\`) } else if (this.data.onReady) { this.getNodeClientReact() } } }, position: { type: String, value: "left" }, foldable: { type: Boolean, value: true }, // 收缩时文字 onFoldText: { type: String, value: "全文" }, // 展开时文字 unFoldText: { type: String, value: "收起" }, }, data: { width: null, onFold: false, showFold: false, onReady: false }, lifetimes: { attached() { this.getNodeClientReact() this.setData({ onReady: true }) }, }, methods: { getNodeClientReact() { setTimeout(() => this.checkFold(), 10) }, checkFold() { const query = this.createSelectorQuery(); query.selectAll(".showArea, .hideArea").boundingClientRect(res => { let showFold = res\[0\].height < res\[1\].height; this.setData({ width: res\[0\].width, showFold, }) }).exec() }, handleFold() { this.setData({ onFold: !this.data.onFold }) } } }) **foldable.wxss** .content { width: 100%; position: relative; overflow: hidden; } .contentInner { word-break: break-all; width: 100%; color: #2f3033; font-size: 30rpx; line-height: 1.35; } .hideArea { display: -webkit-box; overflow: hidden; position: fixed; top: 100vh; left: -100vw; } .foldInner { padding-top: 10rpx; color: #6676bd; font-size: 32rpx; } .foldInner .fold { cursor: pointer; } .text-clamp1 { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; } .text-clamp2 { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; } .text-clamp3 { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; } .text-clamp4 { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; } .text-clamp5 { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5; } ### **2、修复版本** 正常情况下,此方法可行,但是在级别文字下,会计算错误。经过测试,可将 节点是`.hideArea`的内容定位在`.showArea`节点下可解决 **foldable.wxss** .hideArea { display: -webkit-box; overflow: hidden; /\* position: fixed; top: 100vh; left: -100vw; \*/ position: absolute; top: 0; left: 0; z-index: -1; color: #fff; } ### **3、增强版本** 经过修复之后,本来是可以完美实现了,但是在测试过程中,第一次正常渲染是没有问题。但如果文本数据更新,会发现如果原来的文本从一行增加到两行时,使用`wx.createSelectorQuery()`计算的高度会有存在是实际高低的两倍的现象。导致会错误出现`【全文】`文字。然后文本从两行增加到三行或者多行都没问题,不太理解为什么会出现这个错误计算的现象。(期待大神能留言告知 ? ) ![](https://img.php.cn/upload/image/174/945/922/1646653293273716.png) 为了弥补这个坑,我引入了`lineHieght`这个属性。 // foldable.js Component({ properties: { lineHieght: { type: Number, observer(value) { if (!(/^\[0-9\]\*$/).test(value)) { throw new Error(\`lineHieght field value can only be digits\`) } } } } }) 通过`lineHieght`和最多可展示行数`maxLine`可以计算出,可在界面展示的最大高度。 // 文本可见的最大高度 const maxHeight = this.data.lineHieght \* this.data.maxLine; 当然了,我们也需要适配不同的设备,而且通过`wx.createSelectorQuery()`计算出来的结果是以`px`为单位的。 所以,行高需要根据设备尺寸去改变。因为我们是以宽度是`750px`尺寸为设计稿的,所以根据`wx.getSystemInfoSync()`可以获取设备信息,进而转换成`px`的尺寸。 // foldable.js changeRpxToPx(rpxInteger) { return wx.getSystemInfoSync().windowWidth / 750 \* rpxInteger }, 因此,更新`checkFold`方法 checkFold() { const query = this.createSelectorQuery(); query.selectAll(".showArea, .hideArea").boundingClientRect(res => { let showFold = res\[0\].height < res\[1\].height; const lineHeightToPx = this.changeRpxToPx(this.data.LineHeight); // 展示区域高度(即是可能会被截取的可见文字) const showAreaHeight = res\[0\].height; // 隐藏区域的高度(即是完整文本高度,偶然事件会计算错误) const hideAreaHeight = res\[1\].height; // 文本可见的最大高度 const maxHeight = lineHeightToPx \* this.data.maxLine; // 如果是一行文字,偶然计算错误,用行高判断 if (this.data.LineHeight && showAreaHeight <= maxHeight) { showFold = hideAreaHeight > maxHeight } this.setData({ width: res\[0\].width, showFold, }) }).exec() }, ### **4、最终版本** 经过上一个版本,基本功能都已经实现。但是,如果文本超过最大行数,并且在展开全文的情况下,更新了文本,此时,`全文/展开`按钮会展示错误。 ![](https://img.php.cn/upload/image/782/708/283/1646653298326112.png) ![](https://img.php.cn/upload/image/947/335/467/1646653301359435.png) 通过分析代码可知,在展开全文的状态下更新了文本,此时`.showArea`节点和`.hideArea`节点的高度一致,执行代码`let showFold = res[0].height < res[1].height;`,会返回`false`,因此按钮会消失。 因此解决方案为: // 如果文本超出最大行数,并且是显示全文的状态下,再次更新了文字 let onFold = false if (showAreaHeight == hideAreaHeight && showAreaHeight > maxHeight) { showFold = true onFold = true } 所以最终版本的`checkFold`方法是: checkFold() { const query = this.createSelectorQuery(); query.selectAll(".showArea, .hideArea").boundingClientRect(res => { let showFold = res\[0\].height < res\[1\].height; const lineHeightToPx = this.changeRpxToPx(this.data.LineHeight); // 展示区域高度(即是可能会被截取的可见文字) const showAreaHeight = res\[0\].height; // 隐藏区域的高度(即是完整文本高度,偶然事件会计算错误) const hideAreaHeight = res\[1\].height; // 文本可见的最大高度 const maxHeight = lineHeightToPx \* this.data.maxLine; // 如果是一行文字,偶然计算错误,用行高判断 if (this.data.LineHeight && showAreaHeight <= maxHeight) { showFold = hideAreaHeight > maxHeight } // 如果文本超出最大行数,并且是显示全文的状态下,再次更新了文字 let onFold = false if (showAreaHeight == hideAreaHeight && showAreaHeight > maxHeight) { showFold = true onFold = true } this.setData({ width: res\[0\].width, showFold, onFold, }) }).exec() }, ## 四、代码片段 > 经过多次测试,修改,最后附上代码片段: > > https://developers.weixin.qq.com/s/GWj19vmC7oxp > > 各位大神如果有更好的建议,可留言哦~~~ 【相关学习推荐:小程序开发教程】 以上就是聊聊小程序怎么实现“全文收起”功能的详细内容,更多请关注知企PROSAAS其它相关文章! **Categories:** 后端开发 ---