欢迎来到科站长!

JavaScript

当前位置: 主页 > 网络编程 > JavaScript

前端实现文本溢出展开和收起功能

时间:2025-07-22 09:07:25|栏目:JavaScript|点击:

判断文本溢出

众所周知,单行文本溢出打点仅需要:

1
2
3
4
5
.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

而单行文本判断是否溢出的关键就是element.scrollWidth > element.clientWidth

需要注意的是,当使用以上方式判断的时候,不要给元素加上overflow: hidden的样式,不然获取的clientWidth一直都是等于scrollWidth。

示例

先看下元素结构:

1
2
3
4
5
6
7
8
9
<div class="wrapper">
  <div class="text">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. nulla facere
    obcaecati consequatur quisquam adipisci veritatis! Deserunt nostrum
    doloribus minima voluptatum labore.
    <span class="more">展开</span>
    <span class="collapse">收起</span>
  </div>
</div>

文本在.text的元素中,里面有展开收起两个按钮

再写点样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
.wrapper {
  width: fit-content;
  height: fit-content;
  border-radius: 8px;
  border: 1px solid #00bfbf;
  padding: 8px;
}
  
.text {
  width: 300px;
  font-size: 14px;
  line-height: 20px;
}

于是就得到如下图所示的展示效果:

初始化将展开/收起按钮隐藏 

1
2
3
4
5
6
7
/* 展开/收起按钮初始隐藏 */
.text .more {
  display: none;
}
.text .collapse {
  display: none;
}

要使用scrollWidth去判断文本是否溢出,关键需要给.text添加white-space: nowrap;

当需要给.text元素添加单行文本溢出的3行代码,不要直接添加到.text类名下(直接写overflow: hidden就不能使用scrollWidth判断文本溢出了)

另加一个类名,比如:.ellipsis,然后使用js判断文本是否溢出,再给该元素添加该类名。

1
2
3
4
5
.text.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

让.more按钮仅在.ellipsis下展示,再给.more按钮写点样式,css代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/* 溢出 */
.text.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  position: relative;
}
/* 文字溢出 - 展开按钮 */
.text.ellipsis .more {
  display: block;
}
  
.more {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  display: block;
  color: #00bfbf;
  background-color: #fff;
  font-size: 14px;
  line-height: 20px;
  width: fit-content;
  cursor: pointer;
}
  
.more::after {
  content: "";
  display: block;
  position: absolute;
  height: 20px;
  width: 60px;
  right: 28px;
  top: 0;
  background: linear-gradient(
    to right,
    rgba(255, 255, 255, 0),
    rgba(255, 255, 255, 0.6),
    rgba(255, 255, 255, 1)
  );
}

就得到以下效果:

js判断文本溢出如下:

1
2
3
4
5
6
7
8
9
10
11
const isTextOverflowX = (elem) => {
  return text.clientWidth < text.scrollWidth;
};
  
const text = document.getElementsByClassName("text")[0];
  
const isTextOverflow = isTextOverflowX(text);
  
if (isTextOverflow) {
  text.classList.add("ellipsis");
}

判断文本溢出后,才会给文字添加overflow: hidden,为了避免页面文字闪烁,给初始文本元素添加opacity: 0,在判断完毕后,设置opacity: 1

修改一下css,js代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.text {
  ...
  white-space: nowrap;
  opacity: 0;
}
  
/* 未溢出 */
.text.normal {
  white-space: unset; // 让文字正常换行
  opacity: 1;
}
/* 溢出 */
.text.ellipsis {
  ...
  opacity: 1;
}
1
2
3
4
5
if (isTextOverflow) {
  text.classList.add("ellipsis");
} else {
  text.classList.add("normal");
}

分别给展开收起按钮添加点击事件,事件仅需要添加、删除类名即可

1
2
3
4
5
6
7
8
9
10
11
const more = document.getElementsByClassName("more")[0];
more.addEventListener("click", () => {
  text.classList.remove("ellipsis");
  text.classList.add("expand");
});
  
const collapse = document.getElementsByClassName("collapse")[0];
collapse.addEventListener("click", () => {
  text.classList.remove("expand");
  text.classList.add("ellipsis");
});

这里又加了个新类名.expand为了控制文本展开后的按钮显示隐藏

1
2
3
4
5
6
7
8
9
/* 文本展开 */
.text.expand {
  white-space: unset;
  opacity: 1;
}
/* 文本展开 - 收起按钮 */
.text.expand .collapse {
  display: inline-block;
}

最终效果如下:

完整代码

HTML: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>文字溢出隐藏</title>
    <link rel="stylesheet" href="./index.css" rel="external nofollow"  />
    <script src="./index.js" defer></script>
  </head>
  <body>
    <div class="wrapper">
      <div class="text">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Nostrum animi
        cum consequuntur beatae, culpa impedit excepturi fuga, nulla facere
        obcaecati consequatur quisquam adipisci veritatis! Deserunt nostrum
        doloribus minima voluptatum labore.
        <span class="more">展开</span>
        <span class="collapse">收起</span>
      </div>
    </div>
  </body>
</html>

CSS: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
.wrapper {
  width: fit-content;
  height: fit-content;
  border-radius: 8px;
  border: 1px solid #00bfbf;
  padding: 8px;
  margin: 30px auto;
}
  
.text {
  width: 300px;
  font-size: 14px;
  line-height: 20px;
  white-space: nowrap;
  opacity: 0;
}
/* 展开/收起按钮初始隐藏 */
.text .more {
  display: none;
}
.text .collapse {
  display: none;
}
  
/* 未溢出 */
.text.normal {
  white-space: unset;
  opacity: 1;
}
/* 溢出 */
.text.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  position: relative;
  opacity: 1;
}
/* 文字溢出 - 展开按钮 */
.text.ellipsis .more {
  display: block;
}
  
/* 文本展开 */
.text.expand {
  white-space: unset;
  opacity: 1;
}
/* 文本展开 - 收起按钮 */
.text.expand .collapse {
  display: inline-block;
}
  
.more {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  display: block;
  color: #00bfbf;
  background-color: #fff;
  font-size: 14px;
  line-height: 20px;
  width: fit-content;
  cursor: pointer;
}
  
.more::after {
  content: "";
  display: block;
  position: absolute;
  height: 20px;
  width: 60px;
  right: 28px;
  top: 0;
  background: linear-gradient(
    to right,
    rgba(255, 255, 255, 0),
    rgba(255, 255, 255, 0.6),
    rgba(255, 255, 255, 1)
  );
}
  
.collapse {
  color: #00bfbf;
  cursor: pointer;
}

JS: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const isTextOverflowX = (elem) => {
  return text.clientWidth < text.scrollWidth;
};
  
const text = document.getElementsByClassName("text")[0];
  
const isTextOverflow = isTextOverflowX(text);
  
if (isTextOverflow) {
  text.classList.add("ellipsis");
} else {
  text.classList.add("normal");
}
  
const more = document.getElementsByClassName("more")[0];
more.addEventListener("click", () => {
  text.classList.remove("ellipsis");
  text.classList.add("expand");
});
  
const collapse = document.getElementsByClassName("collapse")[0];
collapse.addEventListener("click", () => {
  text.classList.remove("expand");
  text.classList.add("ellipsis");
});

拓展

多行文本溢出

多行文本展开收起的思路一样的

需要修改下文本溢出判断函数,使用clientHeightscrollHeight判断:

1
2
3
const isTextOverflowY = (elem) => {
  return text.clientHeight < text.scrollHeight;
};

.ellipsis溢出css修改为多行文本溢出打点即可

1
2
3
4
5
6
7
.ellipsis {
    overflow : hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}


上一篇:React中FormData的使用实例详解

栏    目:JavaScript

下一篇:vue实现在线进制转换功能

本文标题:前端实现文本溢出展开和收起功能

本文地址:https://www.fushidao.cc/wangluobiancheng/23740.html

广告投放 | 联系我们 | 版权申明

申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:257218569 | 邮箱:257218569@qq.com

Copyright © 2018-2025 科站长 版权所有冀ICP备14023439号