小程序怎么实现“全文收起”功能?下面本篇文章小程序实现多行文本“全文收起”功能的方法,希望对大家有所帮助!
小程序里经常会碰到需要实现多行文本”全文收起“功能,在掘金上有搜索到用纯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
constquery=wx.createSelectorQuery().in(this);query.selectAll(".showArea,.hideArea").boundingClientRect(res=>{console.log(res,'res')}).exec()
三、代码实现
1、初次版本
根据设计思路,立马上手代码
foldable.wxml
<viewclass="content"><viewclass="contentInnercontent-inner-classshowArea{{!onFold?'text-clamp'+maxLine:''}}">{{content}}</view><viewclass="contentInnercontent-inner-classhideArea"style="width:{{width}}px">{{content}}</view><viewclass="foldInnerfold-class{{position==='right'?'flex-end':'flex'}}"wx:if="{{showFold}}"><textclass="fold"catchtap="handleFold">{{onFold?unFoldText:onFoldText}}</text></view></view>
foldable.js
/***长文本内容展开与收起*@param{String}content长文本内容*@param{Number}maxLine最多展示行数[只允许1-5的正整数]*@param{String}position展开收起按钮位置[可选值为leftright]*@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)){thrownewError(`maxLinefieldvaluecanonlybedigits(1-5),Errorvalue:${value}`)}elseif(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(){constquery=this.createSelectorQuery();query.selectAll(".showArea,.hideArea").boundingClientRect(res=>{letshowFold=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.jsComponent({properties:{lineHieght:{type:Number,observer(value){if(!(/^[0-9]*$/).test(value)){thrownewError(`lineHieghtfieldvaluecanonlybedigits`)}}}}})
通过lineHieght和最多可展示行数maxLine可以计算出,可在界面展示的最大高度。
//文本可见的最大高度constmaxHeight=this.data.lineHieght*this.data.maxLine;
当然了,我们也需要适配不同的设备,而且通过wx.createSelectorQuery()计算出来的结果是以px为单位的。
所以,行高需要根据设备尺寸去改变。因为我们是以宽度是750px尺寸为设计稿的,所以根据wx.getSystemInfoSync()可以获取设备信息,进而转换成px的尺寸。
//foldable.jschangeRpxToPx(rpxInteger){returnwx.getSystemInfoSync().windowWidth/750*rpxInteger},
因此,更新checkFold方法
checkFold(){constquery=this.createSelectorQuery();query.selectAll(".showArea,.hideArea").boundingClientRect(res=>{letshowFold=res[0].height<res[1].height;constlineHeightToPx=this.changeRpxToPx(this.data.LineHeight);//展示区域高度(即是可能会被截取的可见文字)constshowAreaHeight=res[0].height;//隐藏区域的高度(即是完整文本高度,偶然事件会计算错误)consthideAreaHeight=res[1].height;//文本可见的最大高度constmaxHeight=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,因此按钮会消失。
因此解决方案为:
//如果文本超出最大行数,并且是显示全文的状态下,再次更新了文字letonFold=falseif(showAreaHeight==hideAreaHeight&&showAreaHeight>maxHeight){showFold=trueonFold=true}
所以最终版本的checkFold方法是:
checkFold(){constquery=this.createSelectorQuery();query.selectAll(".showArea,.hideArea").boundingClientRect(res=>{letshowFold=res[0].height<res[1].height;constlineHeightToPx=this.changeRpxToPx(this.data.LineHeight);//展示区域高度(即是可能会被截取的可见文字)constshowAreaHeight=res[0].height;//隐藏区域的高度(即是完整文本高度,偶然事件会计算错误)consthideAreaHeight=res[1].height;//文本可见的最大高度constmaxHeight=lineHeightToPx*this.data.maxLine;//如果是一行文字,偶然计算错误,用行高判断if(this.data.LineHeight&&showAreaHeight<=maxHeight){showFold=hideAreaHeight>maxHeight}//如果文本超出最大行数,并且是显示全文的状态下,再次更新了文字letonFold=falseif(showAreaHeight==hideAreaHeight&&showAreaHeight>maxHeight){showFold=trueonFold=true}this.setData({width:res[0].width,showFold,onFold,})}).exec()},四、代码片段
经过多次测试,修改,最后附上代码片段:
https://developers.weixin.qq.com/s/GWj19vmC7oxp
各位大神如果有更好的建议,可留言哦~~~
产品猿社区致力收录更多优质的商业产品,给服务商以及软件采购客户提供更多优质的软件产品,帮助开发者变现来实现多方共赢;
日常运营的过程中我们难免会遇到各种版权纠纷等问题,如果您在社区内发现有您的产品未经您授权而被用户提供下载或使用,您可按照我们投诉流程处理,点我投诉;
本文来自用户发布投稿,不代表产品猿立场 ;若对此文有疑问或内容有严重错误,可联系平台客服反馈;
部分产品是用户投稿,可能本文没有提供官方下下载地址或教程,若您看到的内容没有下载入口,您可以在我们产品园商城搜索看开发者是否有发布商品;若您是开发者,也诚邀您入驻商城平台发布的产品,地址:点我进入;
如若转载,请注明出处:https://www.chanpinyuan.cn/33440.html;