小程序如何实现全文收起功能
这篇“小程序如何实现全文收起功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“小程序如何实现全文收起功能”文章吧。
一、需求
位于多行文本右下角,展示”全文/收起“按钮
“展开”和“收起”两种状态的切换
当文本不超过指定行数时,不显示”全文/收起“按钮
文本显示【全文】展示状态下,更新数据,文本不被收起
二、实现思路
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
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: absolute; top: 0; left: 0; z-index: -1; color: #fff;}
3、增强版本
经过修复之后,本来是可以完美实现了,但是在测试过程中,第一次正常渲染是没有问题。但如果文本数据更新,会发现如果原来的文本从一行增加到两行时,使用wx.createSelectorQuery()
计算的高度会有存在是实际高低的两倍的现象。导致会错误出现【全文】
文字。然后文本从两行增加到三行或者多行都没问题,不太理解为什么会出现这个错误计算的现象。
为了弥补这个坑,我引入了lineHieght
这个属性。
// foldable.jsComponent({ 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.jschangeRpxToPx(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 = falseif (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()},
以上就是关于“小程序如何实现全文收起功能”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341