温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

小程序如何实现全文收起功能

发布时间:2022-03-08 09:02:06 来源:亿速云 阅读:166 作者:iii 栏目:移动开发

这篇“小程序如何实现全文收起功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“小程序如何实现全文收起功能”文章吧。

一、需求

  • 位于多行文本右下角,展示”全文/收起“按钮

  • “展开”和“收起”两种状态的切换

  • 当文本不超过指定行数时,不显示”全文/收起“按钮

  • 文本显示【全文】展示状态下,更新数据,文本不被收起

二、实现思路

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()

三、代码实现

1、初次版本

根据设计思路,立马上手代码

foldable.wxml

<view class="content">   <view class="contentInner content-inner-class showArea {{!onFold ? 'text-clamp' + maxLine : ''}}">{{content}}</view>   <view class="contentInner content-inner-class hideArea" style="width: {{width}}px">{{content}}</view>   <view class="foldInner fold-class {{position === 'right' ? 'flex-end' : 'flex'}}" wx:if="{{showFold}}">     <text class="fold" catchtap="handleFold">{{onFold ? unFoldText : onFoldText}}</text>   </view> </view>

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()计算的高度会有存在是实际高低的两倍的现象。导致会错误出现【全文】文字。然后文本从两行增加到三行或者多行都没问题,不太理解为什么会出现这个错误计算的现象。

为了弥补这个坑,我引入了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、最终版本

经过上一个版本,基本功能都已经实现。但是,如果文本超过最大行数,并且在展开全文的情况下,更新了文本,此时,全文/展开按钮会展示错误。

通过分析代码可知,在展开全文的状态下更新了文本,此时.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() },

以上就是关于“小程序如何实现全文收起功能”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI