微信小程序设置超出行显示-...-与展开更多按钮
目录
微信小程序设置超出行显示 … 与展开更多按钮
微信小程序设置超出行显示 … 与展开更多按钮
问题描述
业务开发中会有一些场景,超出一行显示 … 与展开更多按钮,展开更多按钮可以切换显示一行还是全部内容,少于一行正常显示;
解决方案
分析下问题: 一般这种需求不好实现的原因是,在移动端,每行显示的字数的有可能在不同机型会有差异,所以就使开发者无法知道这些内容是否超过一行,是否该显示展开更多按钮。
绕开上述原因,曲线救国,我们在每次页面渲染完成之后再去获取承载内容的元素宽度,和承载内容的元素的外层父级盒子的宽度相对比,如果宽度之差小于半个字体的大小(是为了防止一点误差),则显示 … 的样式,显示展开更多按钮,相反,则隐藏更多按钮。
最终效果如下:
主要代码如下
<view class="coupon-remark-wrapper">
<!--id = toggle-warpper 为包裹内容的父级元素-->
<view class="coupon-remark-content" id="toggle-wrapper">
<!--id = toggle-content 为内容的容器,控制显示全部内容还是显示超出一行... -->
<view id="toggle-content" class="{{toggleParams.toggleFlag === 1?'ellipsis':''}}" hidden="{{toggleParams.toggleFlag === 0}}">
{{couponData.limitRemark}}
</view>
<!--class = toggle-icon 为展开更多按钮-->
<image class="toggle-icon {{toggleParams.toggleFlag === 1?'hide':'show'}}" wx:if="{{toggleParams.toggleShow}}" bindtap="toggleHandler" src="https://img.dmallcdn.com//dshop/201904/b1c5af14-f29a-494c-9e3b-899f1a2cf218"></image>
</view>
</view>
.coupon-remark-wrapper {
padding: 20rpx;
padding-top: 33rpx;
padding-right: 60rpx;
margin-top: -20rpx;
line-height: 1;
box-sizing: border-box;
color: #666666;
background-color: #fff;
position: relative;
z-index: 1;
}
.coupon-remark-content {
width: 100%;
view {
font-size: 22rpx;
line-height: 1.5;
word-break: break-all;
display: inline-block;
max-width: 100%;
}
.ellipsis{
text-overflow:ellipsis;
white-space: nowrap;
overflow: hidden;
}
.toggle-icon {
width: 30rpx;
height: 30rpx;
position: absolute;
right: 20rpx;
top: 35rpx;
transition: all 0.2s linear;
&.show {
transform: rotate(180deg);
}
}
}
const couponItemBehavior = Behavior({
data: {
// 控制说明文案收起/展开
toggleParams: {
toggleFlag: 1, //0收起1展开
toggleShow: false, //默认不显示toggleIcon
},
},
ready() {
this._checkRemarkToggle();
},
methods: {
// 获取指定元素实际宽度
_getElementWidth(id = "") {
let _query = this.createSelectorQuery();
return new Promise(resolve => {
_query.select(id).fields({
size: true,
}, (res) => {
resolve(res.width)
_query = null;
}).exec();
});
},
// 说明文字收起/隐藏事件
toggleHandler() {
const {toggleFlag} = this.data.toggleParams;
this.setData({
toggleParams: {
toggleFlag: toggleFlag === 0 ? 1 : 0,
toggleShow: true
}
})
},
/*
* 检测说明文字是否需要隐藏/收起操作
* 对比文字外层固定宽度容器元素宽度wrapperWidth与当前文字元素宽度contentWidth
* 若相差小于10则说明超出一行
* */
_checkRemarkToggle() {
Promise.all([
this._getElementWidth('#toggle-wrapper'),
this._getElementWidth('#toggle-content')]
).then(res => {
const wrapperWidth = res[0];
const contentWidth = res[1];
const {limitRemark, startDate, endDate, statusCode} = this.properties.couponData;
if (wrapperWidth - contentWidth < 10) {
this.setData({
toggleParams: {
toggleFlag: 1,
toggleShow: true
},
timeArea: `${startDate}-${endDate}`,
unableImageSrc: UNABLE_IMAGE[statusCode]
})
}
})
}
}
});
总结:
在这里只是个抛砖引玉提供一个思路,小程序中可以这样实现,在 H5 中也可以这样实现,如果有更好的方案,欢迎讨论提供!