需求描述
在一个帖子中列表中,文章内容描述超过4行就显示省略号,同时在下方显示出展开按钮,点击展开按钮,展示所有文字,按钮文字替换为收缩
实现过程
需求看起来确实很简单,但是自己实现起来还是遇见了不少坑。最初的想法就是在外层套一层,父容器设置个高度,子容器高度超过就隐藏,并且显示省略号,但是遇见了个问题,就是用css属性现实省略号后,在一些设备上,子容器高度就只有4行,无法用高度来判断了。
先上关键代码吧
<view class="marteial_desc" v-bind:class="{ hide: item.isFlod}">
<view class="marteial_content">{{item.content}}
<text class="marterial_link">{{item.link}}</text>
</view>
</view>
<view class="show_more" @click="showMoreMarterialContent(index,item)">
{{item.isFlod ? "展开" : "收起" }}
</view>
getDescHeight: function() {
this.$nextTick(() => { // 页面渲染完成后的回调
var view = uni.createSelectorQuery().in(this).selectAll(".marteial_desc")
view.fields({
size: true,
computedStyle: ['lineHeight']
}, data => {
data.forEach((element, index) => {
let { height, lineHeight} = element
if (!this.marteialList[index].hasOwnProperty('isFlod')) {
if (height / lineHeight.replace('px', '') > 4) {
// isFlod为true,只显示4行文字,按钮为收起
this.$set(this.marteialList[index], "isFlod", true)
// isShowMoreButton为true,显示按钮
this.$set(this.marteialList[index], "isShowMoreButton",
true)
} else {
// isFlod为false,展开所有文字,隐藏按钮
this.$set(this.marteialList[index], "isFlod", false)
this.$set(this.marteialList[index], "isShowMoreButton",
false)
}
}
})
}).exec()
})
}
showMoreMarterialContent: function(index) {
if (this.marteialList[index]?.isFlod) {
this.$set(this.marteialList[index], "isFlod", false)
} else {
this.$set(this.marteialList[index], "isFlod", true)
}
}
.marteial_desc {
line-height: 32px;
&.hide {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
font-family: "Tahoma";
}
.marteial_content {
font-weight: 300;
color: #333333;
font-size: 26px;
line-height: 32px;
user-select: text;
word-break: break-all;
.marterial_link {
margin-left: 4px;
color: #00B8B0;
}
}
}
主要实现思路就是,通过uni.createSelectorQuery().in(this).selectAll(".marteial_desc")
拿到父容器height和line-height,然后两者相除,判断是否大于4来设置是否折叠,是否显示按钮等状态
遇见的一些坑
1.line-height的值没有拿到
需要在父容器中设置line-heigth的值
2.在一些机型中,通过css设置出来的省略号并没有在下方,反而是垂直居中了
分析了一下原因,可能与你手机设置的字体有关,可以通过设置font-family: "Tahoma";
等来改变,具体用哪种字体,我没有具体研究。
3.两个<text>标签没有在一行显示,并且<text>标签嵌套<text>,内层<text>标签的click事件无法执行
我的做法就是在一个<view>里只设置一个<text>标签,这样前一段的文字样式通过<view>来控制,后一个样式通过<text>来控制。不过如果在一行文字中,需要现实多种字体样式的实现,感觉实现起来就不知道怎么实现了,先记录在此吧,以后有好的实现方法再来更新
实现效果
1.gif