How to implement the "full text collapse" function in the mini program? The following is a small program in this article to implement the "full text collapse" function of multi-line text. I hope it will be helpful to everyone!
In small programs, we often encounter the need to implement the "full text collapse" function of multi-line text. I searched on Nuggets and found that it can be implemented using pure css. Personal test: ios is perfect, but it doesn’t work on andriod.
There are many solutions in the small program community. Currently, I saw a big guy in the community using js dynamic calculation to tell me how to implement it. The personal test has generally been effective. After the test, in some special circumstances There will be errors in the calculation, so some codes have to be changed.
mainly used line-clamp , the key styles are as follows
.text-clamp3 { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; }
Write two paragraphs of text, one paragraph displays the complete text A, A paragraph displays the text B omitted using line-clamp. Because B has been intercepted, the height of B is relatively small. Comparing the height of two pieces of text, you can know whether the text exceeds two lines
In the mini program, you can usewx.createSelectorQuery()
to get the height of the text
js
const query = wx.createSelectorQuery().in(this); query.selectAll(".showArea, .hideArea").boundingClientRect(res => { console.log(res, 'res') }).exec()
According to the design idea, start the code immediately
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; }
Under normal circumstances, this method is feasible, but under level text, calculation errors will occur. After testing, the content of the node .hideArea
can be positioned under the .showArea
node to solve the problem
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; }
After the repair, it could have been implemented perfectly, but during the testing process, there was no problem with the first normal rendering. But if the text data is updated, you will find that if the original text increases from one line to two lines, the height calculated using wx.createSelectorQuery()
will be twice the actual height. As a result, [Full text]
text will appear incorrectly. Then the text increases from two lines to three or more lines without any problem. I don't understand why this miscalculation occurs. (I hope the master can leave a message to inform?)
In order to make up for this pitfall, I introduced the attribute 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`) } } } } })
The maximum height that can be displayed on the interface can be calculated through lineHieght
and the maximum number of displayable lines maxLine
.
// 文本可见的最大高度 const maxHeight = this.data.lineHieght * this.data.maxLine;
Of course, we also need to adapt to different devices, and the result calculated through wx.createSelectorQuery()
is in px
.
So, the row height needs to be changed according to the device size. Because we use the width of 750px
as the design draft, we can obtain the device information according to wx.getSystemInfoSync()
, and then convert it to the size of px
.
// foldable.js changeRpxToPx(rpxInteger) { return wx.getSystemInfoSync().windowWidth / 750 * rpxInteger },
Therefore, update checkFold
method
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() },
After the previous version, the basic functions have been accomplish. However, if the text exceeds the maximum number of lines and the text is updated while the full text is expanded, the Full text/Expand
button will display an error.
It can be seen from the analysis of the code that the text is updated in the state of expanding the full text. At this time, the .showArea
node It is consistent with the height of the .hideArea
node. When executing the code let showFold = res[0].height < res[1].height;
, false
will be returned. , so the button disappears.
So the solution is:
// 如果文本超出最大行数,并且是显示全文的状态下,再次更新了文字 let onFold = false if (showAreaHeight == hideAreaHeight && showAreaHeight > maxHeight) { showFold = true onFold = true }
So the final version of the checkFold
method is:
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() },
After many tests and modifications, the code snippet is finally attached:
https://developers.weixin.qq.com/s/GWj19vmC7oxp
If you have better suggestions, please leave a message~~~
[Related learning recommendations: 小program development tutorial]
The above is the detailed content of Let's talk about how mini programs implement the 'full text collapse” function. For more information, please follow other related articles on the PHP Chinese website!