展开和收起的css实现

展开和收起
功能描述:当文本超过4行,会显示省略号,在省略号后面显示展开按钮,点击可以展开文本,此时省略号展开按钮消失,文本末端出现收起按钮。
分析:一开始采用的是传统的文本溢出隐藏的形式,代码如下,

overflow: hidden;
text-overflow: ellipsis;
/* 弹性伸缩盒子模型显示 */
display: -webkit-box;
/* 限制文本显示行数 */
-webkit-line-clamp: 4;
/* 设置或检索伸缩盒对象的子元素的排列方式 */
-webkit-box-orient: vertical;

但是这种实现无法完成展开收起操作,于是我想参考一下别的网站的写法,很容易想到微博,但是我没有看懂微博是怎么实现的,它的大致规则应该是这样的:
1)超过两段话会进行隐藏
2)对第二段话修改文本,截取前一部分文字(大概是取固定的多少个字),剩下的用省略号代替,并在这一段文本后面追加一个span.expand标签,即展开按钮
3)当点击展开按钮,触发事件,将所有文本重新加载,文本最后追加一个span.collapse标签,即收起按钮

了解微博的大致实现之后,我着手开始自己的实现,但是我遇到两个问题:
1)我不知道该怎么获取到vue中的dom元素的文本行数,很朴素的一个思想是获取到盒子高度和行高,通过计算得出文本行数,于是我搜索如何实现,但是只搜到了jQuery的实现,列如下(突然就感觉jQuery挺好用的):

//html
<div class="txt" style="line-height:30px">我是文字<br>我是文字<br>我是文字<br>我是文字</div>
//jQuery
Math.round($(".txt").height()/parseFloat($(".txt").css('line-height')));

虽然我还搜到了有人在vue中用jQuery获取行数,但是我个人不想用这种大杂烩,肯定还有别的方法。

于是我在$ref获取到的dom元素属性里找了一大圈,希望找到行高的属性,(盒子高度用clientHeight和offsetHeight就行),虽然找到了,但是p.style.lineHeight访问到的值是空,所以这个路走不通了。

【补充】clientHeight:元素的像素高度,包含元素的高度+内边距
offsetHeight:元素的像素高度 包含元素的垂直内边距和边框,水平滚动条的高度,且是一个整数
不考虑滚动条的情况下,offsetHeight只比clientHeight多了边框的部分
文本框我没有设置边框,所以这二者的值是一样的

2)我不知道怎么在传统文本溢出模式下在后面追加一个展开标签,直接将标签追加在文本后面是行不通的,溢出隐藏会隐藏所有超过行数的部分

第二天我浏览博客的时候,看到了纯css实现的展开收起功能,它使用checkbox和label标签配合,点击label标签时checkbox被选中,同时触发省略号展开按钮隐藏,收起按钮显示,最大高度设置取消等事件。给文本盒子添加before伪元素控制省略号展开收起按钮的位置,添加after伪元素实现以下功能:没有超过最大高度时不显示省略号展开按钮。

 <div class="tab-item">
    <input type="checkbox" class="expand-checkbox" id="exp4" />
    <p class="text">
      <label class="expand" for="exp4"></label>
      愿中国青年都摆脱冷气。只是向上走。不必听自暴自弃者流的话。能做事的做事。能发声的 发声。有一分热。发一分光。就令萤火一般。也可以在黑暗里发一点光。不必等候炬火。
    </p>
</div>
.tab-item {
  display: flex;
}
.text {
  font-size: 3.2vw;
  overflow: hidden;
  text-align: justify;
  position: relative;
  line-height: 6.1333vw;
  max-height: 24.5333vw;
  transition: 0.3s max-height;
}

.text::before {
  content: "";
  height: calc(100% - 6vw);
  float: right;
}
.text::after {
  content: "";
  width: 999vw;
  height: 999vw;
  position: absolute;
  box-shadow: inset calc(19vw - 999vw) calc(19vw - 999vw) 0 0 #fff;
  /* opacity: 0.3; */
  margin-left: -13.3333vw;
}
.expand {
  position: relative;
  float: right;
  clear: both;
  margin-left: 2.6667vw;
  font-size: 3.2vw;
  line-height: 6vw;
}
.expand::after {
  content: "展开";
  cursor: pointer;
}
.expand-checkbox {
  display: none;
}
.expand-checkbox:checked + .text {
  max-height: none;
}
.expand-checkbox:checked + .text::after {
  visibility: hidden;
}
.expand-checkbox:checked + .text .expand::before {
  /* visibility: hidden; */
  display: none;
}
.expand-checkbox:checked + .text .expand::after {
  content: "收起";
  cursor: pointer;
}
.expand::before {
  content: "...";
  position: absolute;
  left: -0.2667vw;
  color: #000;
  transform: translateX(-100%);
}
posted @   qiao101  阅读(4328)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示