业务开发中会有一些场景,超出一行显示 … 与展开更多按钮,展开更多按钮能够切换显示一行仍是所有内容,少于一行正常显示;web
分析下问题: 通常这种需求很差实现的缘由是,在移动端,每行显示的字数的有可能在不一样机型会有差别,因此就使开发者没法知道这些内容是否超过一行,是否该显示展开更多按钮。小程序
绕开上述缘由,曲线救国,咱们在每次页面渲染完成以后再去获取承载内容的元素宽度,和承载内容的元素的外层父级盒子的宽度相对比,若是宽度之差小于半个字体的大小(是为了防止一点偏差),则显示 … 的样式,显示展开更多按钮,相反,则隐藏更多按钮。微信小程序
最终效果以下:微信
主要代码以下app
<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 中也能够这样实现,若是有更好的方案,欢迎讨论提供!ide