我需要一个解决方案来动态修剪容器中的多行文本,并以椭圆形结束。
理想情况下CSS(线夹)会处理这个,但浏览器支持只是not there(85.65%)。 - 此外,它目前是“非常脆弱的半成品非标准化财产[y]”(source)。
我目前有一个有效的JavaScript解决方案(测量和弹出,直到它适合),但它的扩展性很差。它受文本长度和夹紧长度之间的差异以及夹紧文本元素的数量的影响。
var trimTextAddEllipses = function (targetElementClassName) {
var elArray = document.getElementsByClassName(targetElementClassName);
Array.from(elArray).forEach(function (el) {
// create a cache of full text in data-attribute to be non-destructive
if (!el.hasAttribute('data-text-cache')) {
el.setAttribute('data-text-cache',el.textContent);
}
// reset
var words = el.textContent = el.getAttribute('data-text-cache');
// turn into array to pop off items until it fits.
var wordArray = words.split(' ');
while (el.scrollHeight > el.offsetHeight) {
wordArray.pop();
el.innerHTML = wordArray.join(' ') + ' …';
}
});
};
对于调整大小,我将其称为回调到requestAnimationFrame调用以限制完成钳位的次数。
这些单词是有序的(即排序的),因此二进制搜索方法可以使代码更有效。
我发现这个this binarySearch函数,但无法提出比较函数,使其正常工作。
我想帮助提出一个与链接二进制搜索功能一起使用的比较函数 - 或者是一个适用于这个问题的不同二进制搜索解决方案。
从评论中我知道在二进制搜索之后还有进一步优化的空间,但是它需要大量的JS工作(即估算而不是测量,从而避免反复渲染) - 但这似乎太难了。
您可以轻松地让循环使用二进制搜索:
let end = wordArray.length, distance = end;
while(distance > 0) {
distance = Math.floor(distance / 2);
el.innerHTML = wordArray.slice(0, end).join(' ') + '...';
end += el.scrollHeight > el.offsetHeight ? -distance : distance;
}