js控制文字溢出显示省略号
.text{
display: -webkit-box;
overflow: hidden;
white-space: normal;
text-overflow: ellipsis;
word-wrap: break-word;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
本人有个需求就是在一个盒子内有一段文本,然后控制文本显示两行,第二行要显示省略号,本人通过以上方式通过
css
解决了
但是有个问题,因为这个区域要被截图保存下来,本人使用html-to-image
插件去完成了截图操作,但就在这时,bug出现了,例如在真机上面显示省略号,但是在截图上面并没有省略号,而是完整的显示出了两行文字,可能由于这个文字大小在当前机型上面刚好溢出,但是没有达到截图的容器的溢出条件,就出现了一个尴尬的事情,截图没省略号,真机有,然后如果多补充点文字,截图虽然显示了省略号,但是省略号前面还是比真机多几个字,,,因此后面不考虑使用css来做了,改成js来做,具体步骤如下:
依赖于jQuery(不推荐)
使用jQuery
和jQuery.ellipsis.js
来解决
jQuery
的代码各位可以百度,这里提供一个CDN地址: https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js
jQuery.ellipsis.js
代码如下:
/*!
* jQuery.ellipsis
* https://github.com/jjenzz/jquery.ellipsis
* --------------------------------------------------------------------------
* Copyright (c) 2013 J. Smith (@jjenzz)
* Dual licensed under the MIT and GPL licenses:
* https://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* adds a class to the last 'allowed' line of text so you can apply
* text-overflow: ellipsis;
*/
(function (a) { if (typeof define === "function" && define.amd) { define(["jquery"], a) } else { a(jQuery) } }(function (d) { var c = "ellipsis", b = '<span style="white-space: nowrap;">', e = { lines: "auto", ellipClass: "ellip", responsive: false }; function a(h, q) { var m = this, w = 0, g = [], k, p, i, f, j, n, s; m.$cont = d(h); m.opts = d.extend({}, e, q); function o() { m.text = m.$cont.text(); m.opts.ellipLineClass = m.opts.ellipClass + "-line"; m.$el = d('<span class="' + m.opts.ellipClass + '" />'); m.$el.text(m.text); m.$cont.empty().append(m.$el); t() } function t() { if (typeof m.opts.lines === "number" && m.opts.lines < 2) { m.$el.addClass(m.opts.ellipLineClass); return } n = m.$cont.height(); if (m.opts.lines === "auto" && m.$el.prop("scrollHeight") <= n) { return } if (!k) { return } s = d.trim(m.text).split(/\s+/); m.$el.html(b + s.join("</span> " + b) + "</span>"); m.$el.find("span").each(k); if (p != null) { u(p) } } function u(x) { s[x] = '<span class="' + m.opts.ellipLineClass + '">' + s[x]; s.push("</span>"); m.$el.html(s.join(" ")) } if (m.opts.lines === "auto") { var r = function (y, A) { var x = d(A), z = x.position().top; j = j || x.height(); if (z === f) { g[w].push(x) } else { f = z; w += 1; g[w] = [x] } if (z + j > n) { p = y - g[w - 1].length; return false } }; k = r } if (typeof m.opts.lines === "number" && m.opts.lines > 1) { var l = function (y, A) { var x = d(A), z = x.position().top; if (z !== f) { f = z; w += 1 } if (w === m.opts.lines) { p = y; return false } }; k = l } if (m.opts.responsive) { var v = function () { g = []; w = 0; f = null; p = null; m.$el.html(m.text); clearTimeout(i); i = setTimeout(t, 100) }; d(window).on("resize." + c, v) } o() } d.fn[c] = function (f) { return this.each(function () { try { d(this).data(c, (new a(this, f))) } catch (g) { if (window.console) { console.error(c + ": " + g) } } }) } }));
引入到页面使用
方式一(固定内容推荐,非动态内容不推荐)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="./jQuery.ellipsis.js"></script>
<style>
.aaa,.aaa2 {
background: #eee;
border: 1px solid #ccc;
width: 130px;
margin-left: 200px;
}
.aaa2{
margin-top: 50px;
}
/* 下面这三个css不能删,否则不起作用了 */
.ellip {
display: block;
height: 100%;
}
.ellip-line {
display: inline-block;
text-overflow: ellipsis;
white-space: nowrap;
word-wrap: normal;
}
.ellip,
.ellip-line {
position: relative;
overflow: hidden;
max-width: 100%;
}
</style>
</head>
<body>
<div class="aaa">
你哈哈哈哈哈哈啊
哈哈哈哈哈哈哈颇大开发跑我就发很日入好闺女诶欧哈你噶IEUR个
</div>
<div class="aaa2">你哈哈哈哈哈哈啊 哈哈哈哈哈哈哈颇大开发跑我就发很日入好闺女诶欧哈你噶IEUR个</div>
<script>
$('.aaa').ellipsis({ lines: 2 }); // 控制第二行溢出显示省略号
$('.aaa2').ellipsis({ lines: 2 }); // // 控制第二行溢出显示省略号
</script>
</body>
</html>
上面内容可以看到,需要换行的部分必须手动在html里面加换行或者
,因此这种方式适合静态的,不适用于动态的,可以看下面这个
方式二(动态内容推荐)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="./jQuery.ellipsis.js"></script>
<style>
.aaa {
background: #eee;
border: 1px solid #ccc;
width: 150px;
}
/* 下面这三个css不能删,否则不起作用了 */
.ellip {
display: block;
height: 100%;
}
.ellip-line {
display: inline-block;
text-overflow: ellipsis;
white-space: nowrap;
word-wrap: normal;
}
.ellip,
.ellip-line {
position: relative;
overflow: hidden;
max-width: 100%;
}
</style>
</head>
<body>
<div class="aaa">abababababa我还得覅维护诶哈哈哈哈哈哈颇大开发跑我就发很日入好闺女诶欧哈你噶IEUR个</div>
<script>
function getTextWidth(text, font) {
// 计算字符串的宽
// 创建临时canvas元素
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
context.font = font;
return context.measureText(text).width;
}
let aaa = document.querySelector('.aaa'); // 获取容器
let aaawidth = aaa.clientWidth; // 拿到容器的宽度
let text = aaa.innerText;
let font = getComputedStyle(aaa).font; // 获取元素的实际字体样式(为了算文字大小)
let textWidth = getTextWidth(text, font); // 计算字符串的宽度
console.log(aaawidth,textWidth); // 容器的宽和字符串的宽度
let textarr = text.split('') // 将字符串分割成数组进行遍历
let start_str = '' // 第一行的文字内容
let end_str = '' // 第二行的文字内容(还可以加其他更多的行,只需要在下面多几个判断就好)
let linshistr = '' // 临时存储用于计算的字符串
textarr.forEach((item)=>{
linshistr += item // 每次循环都让临时字符串累加
// 下面如果有第二行第三行的话直接判断 > n*aaawidth 即可
if(getTextWidth(linshistr, font) > aaawidth){
// 如果小于容器容器宽度,让第一行的字符串进行累加
end_str += item
}else{
// 如果超出容器,都是在第二行,直接让第二行元素累加
start_str+= item
}
})
console.log(start_str, end_str); // 获取第一行和第二行元素内容
aaa.innerHTML = start_str + ' ' + end_str // 加个 可以换行,就像方式一写死的一样
$('.aaa').ellipsis({ lines: 2 }); // 再去使用jQuery.ellipsis.js的ellipsis方法让第二行显示省略号
</script>
</body>
</html>
直接使用js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.aaa {
background: #eee;
border: 1px solid #ccc;
width: 150px;
}
</style>
</head>
<body>
<div class="aaa">
<div class="son"></div>
<div class="son2"></div>
</div>
<script>
let str = 'a我还得覅维护诶哈哈哈哈哈哈颇大开发跑我就发很日入好闺女诶欧哈你噶IEUR个' // 获取文本内容
function getTextWidth(text, font) {
// 计算文本字符串的宽
// 创建临时canvas元素
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
context.font = font;
return context.measureText(text).width;
}
// 获取元素实际的容器
let aaa = document.querySelector('.aaa');
let aaawidth = aaa.clientWidth; // 获取容器宽度
let font = getComputedStyle(aaa).font; // 获取元素的实际字体样式,(为了算文字大小,这个跟字符串的宽有影响)
let textWidth = getTextWidth(str, font); // // 计算字符串的宽度
console.log(aaawidth, textWidth); // // 容器的宽和字符串的宽度
let textarr = str.split('') // 将字符串分割成数组进行遍历
let start_str = '' // 第一行的文字内容
let end_str = '' // 第二行的文字内容(还可以加其他更多的行,只需要在下面多几个判断就好)
let linshistr = '' // 临时存储用于计算的字符串
textarr.forEach((item) => {
linshistr += item
// 第一行的判断
if (getTextWidth(linshistr, font) < aaawidth) {
start_str += item
}
// 第二行的判断
if (getTextWidth(linshistr, font) > aaawidth && getTextWidth(linshistr, font) < 2 * aaawidth) {
end_str += item
}
// 第n行的判断
// if (getTextWidth(linshistr, font) > ( n - 1 ) * aaawidth &&getTextWidth(linshistr, font) > n * aaawidth) {}
})
console.log(start_str, end_str); // 输出第一行和第二行的文字内容
function wordLength(e) {
var length = 0
var arr = e.split('')
arr.map(function (char) {
if (char.charCodeAt(0) > 255) {
//字符编码大于255,说明是双字节字符(中文占两个字符,英文大小写,特殊字符等都是一个字符)
length += 2
} else {
length++
}
})
return length
}
let zijie = wordLength(start_str + end_str) // 判断下字节长度,中文字占两个,英文特殊字符等占一个
let flag = zijie % 2 == 0 ? true : false // 判断是否是偶数,如果是偶数,让省略号那里减去1,否则减去2,因为比如某一行全部是中文,那这一行的字节肯定是偶数,如果是奇数,没有减够,则会被溢出一行,如果都减2,第二行就显得被缩回了一点
document.querySelector('.son').innerHTML = start_str
document.querySelector('.son2').innerHTML = flag ? (end_str.substring(0, end_str.length - 1) + '...') : (end_str.substring(0, end_str.length - 2) + '...');
</script>
</body>
</html>