微信小程序
现在有一个需求,当文本超过两行溢出显示省略号,并在末尾展示展开按钮
我现在的做法是动态绑定class类名,当他的字符长度超过45的时候就
if (item.reply && item.reply.length < 45) item.replyFlag = true
// reply字段就是返回的文字
这是正常显示
当输入的数字就会这样这里的长度都还没到45
当输入的英文长度==45的时候就会这样
width: 94%;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
word-wrap: break-word;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
// 这是长度不超过45的样式
// 超过45的时候
// -webkit-line-clamp:inherit
请问这种怎么解决或者还有别的更好的方式处理吗
小程序组件封装
设置行高,2行多高换算成px,这里组件是5行换算成px是126,渲染后获取元素高度判断是否超出,超出增加对应样式和控制显示展开按钮
wx.js
import random from 'lodash.random';
Component({
options: { addGlobalClass: true },
properties: {
text: String,
},
data: {
showExpande: false,
ellipsis: false,
id: '',
},
lifetimes: {
ready() {
if (this.data.text) {
this.init();
}
},
},
methods: {
onToggle() {
this.setData({ ellipsis: !this.data.ellipsis });
},
init() {
this.setData({ id: 'content' + Date.now() + random(100000, 999999).toString() }, () => {
const query = wx.createSelectorQuery().in(this);
query.select(`#${this.data.id}`).boundingClientRect((res) => {
const showExpande = res?.height > 126;
this.setData({ showExpande });
}).exec();
});
},
},
});
wx.wxml
<view wx:if="{{text}}" class="act-detail_intro border-box pd-20 mt-40 radius-24 flex-column">
<view class="font-28 {{!ellipsis ? 'ellipsis-5' : ''}}">
<text id="{{id}}" decode space>{{text}}</text>
</view>
<view class="fold_btn width-full flex-end font-28" bindtap="onToggle" wx:if="{{showExpande}}">{{!ellipsis ? '展开' : '收起'}}</view>
</view>
wx.wxss
.act-detail_intro {
background: rgba(255, 255, 255, 0.2);
font-weight: 400;
color: #ffffff;
line-height: 42rpx;
}
.act-detail_intro .fold_btn {
font-weight: 400;
line-height: 42rpx;
color: rgba(255, 255, 255, 0.2);
}
.ellipsis-5 {
display: -webkit-box;
-webkit-box-orient: vertical;
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 5;
line-clamp: 5;
}
wx.json
{
"component": true,
"usingComponents": {}
}
replyFlag定义三个值,0、1、2分别代表不显示,展开状态,收起状态
然后你再根据字数赋值
因为你设置的字符长度,一个英文单词就是一个字符,推荐一种写法,把溢出省略单独写到一个css样式里面,然后判断这个文本的高度,超过某个界限的时候添加溢出省略的css样式,并添加一个展开,收起的按钮
现在是判断字符长度,换成判断元素高度,超过两行的高度就给它折叠显示...
应该没有 太好的 方法了 。用css 控制就行 。判读字符 长度
css 里加上这个属性:
word-break: break-all;
建议选择用css控制超出两行省略显示,根据高度变化判断是否显示展开收起按钮
1、计算实际行高。createElement div插入文字,一行文字的时候行高是多少,然后乘2,计算最大行高。
2、判断当前实际文字的行高是多少,未超过上个步骤中最大行高则直接将内容返回显示。
3、如果超过了最大行高,那么需要写个递归算法,对文字不断截取插入,看行高是否超过最大行高,直到找到最合适的文字长度。
4、点击更多增将原来的完整的文字插入。
因为写起来太费劲,所以未完整实现。我实际参考ant-design-vue typography组件实现方式分解的步骤,你可以去看看它的源码。
定义内容占位盒子A溢出ellipsis,内容B宽度能自动auto,收起展开按钮C会跟着内容auto变化往右挤:
1.当C被B挤出来超出A的宽度了就可见;
2.当C被B挤出来没能超出A的宽度了就不可见,类似于C被A遮盖住了一样
3.收起展开按钮切换控制切换一下A的高度auto
用这种思想来实现足够了
为什么要判断字符长度呢,不是说的是两行蒙,不同屏幕大小不一样啊,可输入字符长度也不一样,所以直接判断div超出就显示
实现方案一: 采用js的方式,首先判断元素是否超过了两行,超过的话截取前N个字符拼接上省略号 ... 展示;不超过两行正常展示。判断元素内容是否超过 n 行的方法如下:
/**
* 工具方法参数类型
*/
export interface MoreThanLineParams {
containerClassName: string; // 父元素类名,需包含字号属性
width: number; // 行宽度
content: string; // 内容
line?: number; // 行数
}
/**
* 判断元素是否超过n行
* 默认两行
*/
export const moreThanLines = ({
containerClassName,
content,
width,
line = 2,
}: MoreThanLineParams) => {
let result = false;
// 用于存放内容的元素
const tempNode = document.createElement('div');
tempNode.setAttribute('id', 'temp-node');
tempNode.style.position = 'absolute';
tempNode.style.visibility = 'hidden';
// 将传递进来的类名和文本内容赋值
tempNode.classList.add(containerClassName);
tempNode.style.width = width + 'px';
tempNode.innerHTML = content;
const containerNode = document.body.appendChild(tempNode);
// 用于计算行高的元素
const dupNode = document.createElement('div');
dupNode.classList.add(containerClassName);
dupNode.style.width = width + 'px';
dupNode.style.wordBreak = 'keep-all';
dupNode.style.overflowWrap = 'normal';
dupNode.style.whiteSpace = 'nowrap';
dupNode.style.position = 'absolute';
dupNode.innerHTML = content.substring(0, 2);
dupNode.setAttribute('id', 'copy-node');
const getLineHeightNode = document.body.appendChild(dupNode);
if (containerNode.offsetHeight > getLineHeightNode.offsetHeight * line) {
result = true;
}
document.body.removeChild(containerNode);
document.body.removeChild(getLineHeightNode);
return result;
};
【CSS 文字截断技巧】https://zhuanlan.zhihu.com/p/35713421
【CSS 实现多行文本展开收起效果】https://github.com/sisterAn/blog/issues/120