UI需求:文字超过限定的行数,可点击“展开”“收起”,隐藏和显示文字内容。具体要求如下:
1.文章内容字数过多时默认展示三行,在第三行的末尾防止“展开”按钮,当点击展开时显示所有文章内容;
2.被展开的内容末尾有“收起”按钮,和最后一行内容在同一行中,如果最后一行内容过多,“收起”按钮可换到下一行,居右展示。
方法如下:
通过“用伪元素展示多行内容超出省略并在行末可点击展开”解决了此问题,直接上代码。
此方法处理起来虽然麻烦,但本人认为效果是最好的!
main.js
function refreshRem() {
const designSize = 1440; // 设计图尺寸
const html = document.documentElement;
let wW = html.clientWidth; // 窗口宽度
if (wW > 1440) {
wW = 1440;
}
let rem = (wW * 14) / designSize;
if (wW <= 800) {
rem = (wW * 14) / 375;
}
document.documentElement.style.fontSize = rem + "px";
// getComputedStyle能获取被系统放大后的字体
let computedFontSize = window.getComputedStyle(document.getElementsByTagName("html")[0])['font-size'].replace(/px/gi, '');
// 被放大的字体倍数
let multiple = (Math.floor(computedFontSize / rem * 1000)/1000).toFixed(3)
// 将浏览器的字体缩放比例存到window下
window.multiple = multiple
}
(function (win) {
let tid;
win.addEventListener(
"resize",
function () {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
},
false
);
win.addEventListener(
"pageshow",
function (e) {
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
},
false
);
refreshRem();
})(window);
A.vue
<template>
<div class="spread">
<div class="top-prove">为了证明下面的内容不会对我造成影响</div>
<div v-for="(item,index) in list">
<div :class="item.showTotal ? 'init-content' : 'detail-content'">
<div
:title="item.answer"
:id="item._id"
:style="{
'--multiple': multiple,
'--multiple-before': multipleBefore,
'--multiple-after': multipleAfter
}"
class="title-content">
<span class="empty-content">{{ item.answer }}</span>
<div v-if="item.showButton" @click="showOrHidden(index)" class="unfold">
{{ item.buttonType ? "展开" : "收起" }}
</div>
</div>
</div>
</div>
<div class="bottom-prove">为了证明上面的内容不会对我造成影响</div>
</div>
</template>
<script>
export default {
name: 'Spread',
data() {
return {
multiple: (window.multiple * 72 / 14) + "rem", //div元素的最大高度
multipleBefore: (window.multiple * 48 / 14) + "rem", //div元素的before伪元素显示2行内容的高度
multipleAfter: (window.multiple * 72 / 14) + "rem", //div元素的after伪元素显示3行内容的高度
list: [
{"_id":"c4d069c1-8413-4c47-91b8-ec1dc51692dc","answer":"떠나지 마 just stay\n\n不要离开 在此停留\n\n지금 이 시간을 멈춘 채\n\n此刻时间停滞\n\n너와 함께라면 난\n\n只要能和你在一起\n\nI could die in this moment\n\nForever young\n\nForever young\n\nForever young\n\nForever young\n\n너의 눈에 비친 나의 모습이\n\n你的眼眸中倒映出我的身影\n\n늘 처음 만난 그 날만 같길\n\n总是如初见那般炙热\n\n소리 없이 타오르는 불꽃같이\n\n伴随着悄无声息燃烧的火花\n\n마지막처럼 내 입 맞추길\n\n像最后一次那般亲吻我\n\n달빛 아래 내 마음은 설레\n\n皎洁的月光下 我心动不已\n\n은하수로 춤추러 갈래 let's go\n\n让我们到银河去跳舞吧\n\n지금 let go\n\n现在 let go오늘이 가도 후회 없게\n\n又是不留遗憾的一天\n\n시간이 우리 둘을 떼어 놓을 수 없게\n\n时间无法让我们分开\n\n순간이 영원할 수 있게\n\n瞬间即永恒\n\n넌 내 마음에 불을 질러줘\n\n你在我的心上纵火吧\n\n후회 없는 젊음이 타오르게\n\n让无悔的青春燃烧\n\n지금처럼 너와 함께라면 tonight\n\n只要能像此刻这样和你在一起 今晚\n\nI could die in this moment"}
]
};
},
mounted() {
this.init();
},
methods: {
showOrHidden(i) {
//展开、收起
this.$set(this.list[i], "showTotal", !this.list[i].showTotal);
this.$set(this.list[i], "buttonType", !this.list[i].buttonType);
// if (this.list[i]["buttonType"]) {
// // 如果是展开状态,记录下滚动条位置
// this.list[i].scrollTop = document.body.scrollTop + document.documentElement.scrollTop;
// this.$set(this.list[i], "buttonType", false);
// } else {
// // 如果是收起状态,滚动到收起的位置
// document.body.scrollTop = this.list[i].scrollTop;
// document.documentElement.scrollTop = this.list[i].scrollTop;
// this.$set(this.list[i], "buttonType", true);
// }
},
init() {
//异步请求到列表list
this.$nextTick(() => {
for (let i = 0; i < this.list.length; i++) {
const item = this.list[i];
const id = item._id;
const dom = document.getElementById(id);
//判断div标签内的内容是否超过元素的最大高度,若小于最大高度则展示全部文字,大于最大高度则可“展开/收起”
if (dom.scrollHeight > dom.offsetHeight) {
// 显示展开收起按钮
this.$set(this.list[i], "showButton", true);
this.$set(this.list[i], "buttonType", true);
// 不是显示所有
this.$set(this.list[i], "showTotal", false);
} else {
// 不显示展开收起按钮
this.$set(this.list[i], "showButton", false);
this.$set(this.list[i], "buttonType", false);
// 显示所有
this.$set(this.list[i], "showTotal", true);
}
}
});
},
},
};
</script>
less.js
<style lang="less" scoped rel="stylesheet/less">
@s: 14rem;
.spread {
.top-prove, .bottom-prove {
min-height: (72 / @s);
background-color: #ccc;
}
//文字不足三行展示全部的样式
.init-content {
font-size: ( 14 / @s);
height: auto;
overflow: hidden;
color: #2B3439;
margin-bottom: (12 / @s);
opacity: 0.5;
.title-content {
max-height: (72 / @s);
.empty-content {
width: 100%;
line-height: (24 / @s);
}
}
.unfold {
cursor: pointer;
display: block;
z-index: 11;
float: right;
color: #2B3439;
text-decoration: underline;
}
}
// 文字超过三行时的样式
.detail-content {
font-size: ( 14 / @s);
color: #2B3439;
position: relative;
overflow: hidden;
margin-bottom: (12 / @s);
opacity: 0.5;
.title-content {
// max-height: (72 / @s);
max-height: var(--multiple); //动态设置元素的高度
line-height: (24 / @s);
word-wrap: break-word;
/*强制打散字符*/
word-break: break-all;
background: #ffffff;
/*同背景色*/
color: #ffffff;
overflow: hidden;
-moz-user-select:none;
-webkit-user-select:none;
-ms-user-select:none;
-khtml-user-select:none;
user-select:none;
&:after, &:before {// 这是展开前实际显示的内容
content: attr(title);
position: absolute;
left: 0;
top: 0;
width: 100%;
color: #2B3439;
}
// 把最后一行自身的上面2行遮住
&:before {
display: block;
overflow: hidden;
z-index: 1;
// height: (48 / @s);
height: var(--multiple-before); //*显示2行的高度 */
background: #ffffff;
}
&:after {
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
// height: (72 / @s);
height: var(--multiple-after); //*显示3行的高度 */
/*截取行数*/
-webkit-line-clamp: 3;
text-overflow: ellipsis;
-webkit-box-sizing: border-box;
box-sizing: border-box;
/*行首缩进字符数*/
text-indent: -(112 / @s);
/*尾部留空字符数*/
padding-right: (56 / @s);
}
.unfold {
cursor: pointer;
z-index: 11;
outline: 0;
position: absolute;
right: 0;
bottom: 0;
color: #2B3439;
text-decoration: underline;
}
}
}
}
</style>