判断文本溢出
众所周知,单行文本溢出打点仅需要:
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
而单行文本判断是否溢出的关键就是element.scrollWidth
> element.clientWidth
需要注意的是,当使用以上方式判断的时候,不要给元素加上overflow: hidden
的样式,不然获取的clientWidth
一直都是等于scrollWidth
示例
先看下元素结构:
<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
的元素中,里面有展开、收起两个按钮
再写点样式:
.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;
}
于是就得到如下图所示的展示效果
初始化将展开
/收起
按钮隐藏
/* 展开/收起按钮初始隐藏 */
.text .more {
display: none;
}
.text .collapse {
display: none;
}
要使用scrollWidth
去判断文本是否溢出,关键需要给.text
添加white-space: nowrap;
当需要给.text
元素添加单行文本溢出的3行代码,不要直接添加到.text
类名下(直接写overflow: hidden
就不能使用scrollWidth判断文本溢出了)
另加一个类名,比如:.ellipsis
,然后使用js判断文本是否溢出,再给该元素添加该类名
.text.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
让.more
按钮仅在.ellipsis
下展示,再给.more
按钮写点样式,css代码如下:
/* 溢出 */
.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判断文本溢出如下:
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代码
.text {
...
white-space: nowrap;
opacity: 0;
}
/* 未溢出 */
.text.normal {
white-space: unset; // 让文字正常换行
opacity: 1;
}
/* 溢出 */
.text.ellipsis {
...
opacity: 1;
}
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");
});
这里又加了个新类名.expand
为了控制文本展开后的按钮显示隐藏
/* 文本展开 */
.text.expand {
white-space: unset;
opacity: 1;
}
/* 文本展开 - 收起按钮 */
.text.expand .collapse {
display: inline-block;
}
最终效果如下
完整代码
<!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" />
<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>
.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;
}
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");
});
拓展
多行文本溢出
多行文本展开收起的思路一样的
需要修改下文本溢出判断函数,使用clientHeight
、scrollHeight
判断:
const isTextOverflowY = (elem) => {
return text.clientHeight < text.scrollHeight;
};
.ellipsis
溢出css修改为多行文本溢出打点即可
.ellipsis {
overflow : hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
展开按钮前面展示...
展开按钮处不使用透明遮罩,使用...
待续...