js实现多行文本省略

最近有移动端实现多行省略需求,在实现的过程发现css无法完全满足需求,于是就萌生出通过js来实现的想法,说干就干。

css单行文本省略

单行的看看就好,就不逼逼了。

// css里设置
<style type="text/css">
	元素 {
	    overflow: hidden;
	    text-overflow:ellipsis;
	    white-space: nowrap;
            width: 400px;
	}
</style>
复制代码

效果图:


css实现多行文本省略

多行文本设置webkitLineClamp等一些属性就好,但是它目前只对google,safari浏览器支持,其他的浏览器无法进行css多行文本样式的省略。

// css里设置
<style type="text/css">
	元素 {
	    display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 2;
		overflow: hidden;
		width: 400px;
	}
</style>
复制代码

效果图:


js实现多行文本省略

1、给需要省略的标签添加类名:mapleTextareaOverFlow和行数:rows;
2、判断是否有webkitLineClamp属性,有的话直接添加css样式省略;没有则进行计算;
3、超过行数则省略,不超过则不管;

html
<body>
    <p class="mapleTextareaOverFlow" rows='1'>
		人生不如意常十八九,要让自己快乐,就必须给自己减压,减压的好方法就是学会忘记,人生需要能拿得起,有时候放得下更重要。
	</p>
	<p class="mapleTextareaOverFlow" rows='2'>
		人生不如意常十八九,要让自己快乐,就必须给自己减压,减压的好方法就是学会忘记,人生需要能拿得起,有时候放得下更重要。
	</p>
	<p class="mapleTextareaOverFlow" rows='3'>
		人生不如意常十八九,要让自己快乐,就必须给自己减压,减压的好方法就是学会忘记,人生需要能拿得起,有时候放得下更重要。
	</p>
</body>
复制代码
js的实现
// 获取需要设置多行省略的标签
const elBoxs = document.getElementsByClassName('mapleTextareaOverFlow');
const elBoxsLength = elBoxs.length;

for(let i = 0; i < elBoxsLength; i += 1) {
	const el = elBoxs[i];
        let text = el.innerHTML;
        // 需要在第几行省略,是否支持webkitLineClamp属性
        let options = {
		rows: parseInt(el.getAttribute('rows')),
		isSupportlineCamp: `${el.style.webkitLineClamp}` !== 'undefined',
	};

	// 设置需要省略的属性及字体的两端对齐的样式
	el.style.overflow = 'hidden';
	el.style.textOverflow = 'ellipsis';
	el.style.wordBreak = 'break-all';
	el.style.wordWrap = 'break-word';
	el.style.textAlign = 'justify';

         // 支持webkitLineClamp的话直接使用浏览器css样式设置省略号(safari不是很支持,可以直接使用js计算方式),否则通过计算方式
	if(options.isSupportlineCamp) {
		el.style.webkitLineClamp = options.rows;
		el.style.display = '-webkit-box';
		el.style.webkitBoxOrient = 'vertical';
	} else {
		const heightStr = getCurrentStyle(el, 'height');
		const height = getNumber(heightStr);
		const maxHeight = getMaxHeight(el, options.rows, text);
		if(height > maxHeight) {
			subStrChar(el, maxHeight, text);
		} else {
			el.innerHTML = text;
		}
	}
};

// 截取字符串,从第一个开始,当前高度大于最大高度时,截取到前一个字符;
function subStrChar(el, maxHeight, text) {
	console.log(maxHeight);
	let end = false;
	let i = 0;
	while(!end) {
		i++;
		el.innerHTML = text.substring(0, i) + '...';
		const currentHeightStr = getCurrentStyle(el, 'height');
		const currentHeight = getNumber(currentHeightStr);
		if(currentHeight > maxHeight) {
			el.innerHTML = text.substring(0, i - 1) + '...';
			end = true;
		}
		if(i >= text.length) {
			break;
		}
	}
}

// 获取最大高度,当line-height为normal的时候,对标签塞入字符,获取一行的行高
function getMaxHeight(el, rows, text) {
	const lineHeight = getCurrentStyle(el, 'lineHeight');
	let number = 0;

	if(lineHeight === 'normal') {
		let index = 0;
		do {
			el.innerHTML = text[index++];
		} while(!getNumber(getCurrentStyle(el, 'height')));
		number = getNumber(getCurrentStyle(el, 'height'));
	} else {
		number = getNumber(lineHeight);
	}

	return number * rows;
}

// 获取当前元素的属性值
function getCurrentStyle(el, elAttr) {
        // getComputedStyle获取元素的所有CSS属性的值
	return window.getComputedStyle(el)[elAttr]
}

// 将获取的字符串值变成向上取整成数字
function getNumber(str) {
	let number = parseFloat(str);
	return Math.ceil(number)
}
复制代码

到这基本上就完事

注意

注意

注意,重要的事说三遍

safari浏览器会出现重叠的情况,可以摒弃webkitLineClamp,直接计算。
复制代码

转载于:https://juejin.im/post/5c7cf79f518825407206afc1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值