如何计算 DOM 元素内的文本行数?我可以吗?

IT技术 javascript html dom
2021-01-22 13:20:52

例如,我想知道是否有一种方法可以计算 div 内的行数。假设我们有一个像这样的 div:

<div id="content">hello how are you?</div>

根据许多因素,div 可以有一行、两行,甚至四行文本。有没有办法让脚本知道?

换句话说,在 DOM 中是否表示自动中断?

6个回答

如果 div 的大小取决于内容(我假设您的描述是这种情况),那么您可以使用以下方法检索 div 的高度:

var divHeight = document.getElementById('content').offsetHeight;

并除以字体行高:

document.getElementById('content').style.lineHeight;

或者在没有明确设置的情况下获取行高:

var element = document.getElementById('content');
document.defaultView.getComputedStyle(element, null).getPropertyValue("lineHeight");

您还需要考虑填充和行间距。

编辑

完全独立的测试,明确设置行高:

function countLines() {
   var el = document.getElementById('content');
   var divHeight = el.offsetHeight
   var lineHeight = parseInt(el.style.lineHeight);
   var lines = divHeight / lineHeight;
   alert("Lines: " + lines);
}
<body onload="countLines();">
  <div id="content" style="width: 80px; line-height: 20px">
    hello how are you? hello how are you? hello how are you? hello how are you?
  </div>
</body>

再想一想,行高不必总是数字(或以像素为单位)。因此,如果您的代码依赖它并且您的 CSS 约定允许它,您可能应该以像素为单位设置行高。
2021-03-11 13:20:52
这可能仅适用于最简单的情况(如我的示例)。如果内部有跨度、内联块元素等,直接按(父)字体大小划分是没有value的。不过,总比没有好,谢谢。
2021-03-17 13:20:52
这是一个好的开始,只是行高可能并不总是被设置。你应该从元素的计算样式中得到它。
2021-03-23 13:20:52
@Chetan - 以像素为单位设置文本尺寸通常被认为是一件坏事。astahost.com/Sizes-Webdesign-Em-Vs-Px-t8926.html
2021-03-27 13:20:52
我认为获得计算line-height(未明确设置)的更好方法是使用window.getComputedStyle(element, null).getPropertyValue('line-height')
2021-04-07 13:20:52

查看可用于计算元素中行数的函数getClientRects()这是一个如何使用它的示例。

var message_lines = $("#message_container")[0].getClientRects();

它返回一个 javascript DOM 对象。通过这样做可以知道行的数量:

var amount_of_lines = message_lines.length;

它可以返回每行的高度,等等。通过将其添加到您的脚本中,然后查看您的控制台日志,查看它可以执行的所有操作。

console.log("");
console.log("message_lines");
console.log(".............................................");
console.dir(message_lines);
console.log("");

虽然需要注意的一些事情是它只在包含元素是内联的情况下才有效,但是你可以用块元素包围包含的内联元素来控制宽度,如下所示:

<div style="width:300px;" id="block_message_container">
<div style="display:inline;" id="message_container">
..Text of the post..
</div>
</div>

虽然我不建议像那样硬编码风格。这仅用于示例目的。

添加到这一点,如果你需要找到的行数,当有嵌套元素(astrong等)试试这个codesandbox.io/s/adoring-wind-v6s6h
2021-03-12 13:20:52
@klm123 您需要将元素设置为 display: inline
2021-03-22 13:20:52
getClientRects().length 在 Opera 和 Chrome 中总是为我返回 1
2021-03-27 13:20:52
这个和其他基于 getClientRects 的答案比公认的好得多
2021-04-03 13:20:52
这应该是公认的答案。谢谢@Digital-Christie
2021-04-04 13:20:52

一种解决方案是使用脚本将每个单词都包含在 span 标签中。然后,如果给定跨度标记的 Y 维度小于其直接前任的 Y 维度,则发生换行。

我的 div 有文本和图像......幸运的是图像是绝对定位的,所以我认为它们会被排除在外。:D 无论如何,我使用了您建议的相同代码,但 div 不是跨度,谢谢+1!
2021-03-18 13:20:52
聪明的!你是怎样做的?我猜你假设只有文本段落(就像我在示例中所做的那样)。我没有想到这个限制,但它可能没问题,前提是当段落中有其他内容时脚本不会崩溃。
2021-03-26 13:20:52
再想一想,如果行中有垂直对齐的跨度,则此方法将失败。因此,即使是纯文本的段落也可能被错误地计数。
2021-04-05 13:20:52

我对这里和其他问题的答案不满意。评分最高的答案没有考虑paddingborder考虑,因此显然也忽略box-sizing了。我的回答结合了这里和其他线程上的一些技术,以获得令我满意的解决方案。

它并不完美:当无法检索到line-height(例如normalinherit)的数值时,它仅使用font-size乘以1.2也许其他人可以建议一种可靠的方法来检测这些情况下的像素值。

除此之外,它已经能够正确处理我抛出的大多数样式和案例。

jsFiddle用于播放和测试。下面也内联。

function countLines(target) {
  var style = window.getComputedStyle(target, null);
  var height = parseInt(style.getPropertyValue("height"));
  var font_size = parseInt(style.getPropertyValue("font-size"));
  var line_height = parseInt(style.getPropertyValue("line-height"));
  var box_sizing = style.getPropertyValue("box-sizing");
  
  if(isNaN(line_height)) line_height = font_size * 1.2;
 
  if(box_sizing=='border-box')
  {
    var padding_top = parseInt(style.getPropertyValue("padding-top"));
    var padding_bottom = parseInt(style.getPropertyValue("padding-bottom"));
    var border_top = parseInt(style.getPropertyValue("border-top-width"));
    var border_bottom = parseInt(style.getPropertyValue("border-bottom-width"));
    height = height - padding_top - padding_bottom - border_top - border_bottom
  }
  var lines = Math.ceil(height / line_height);
  alert("Lines: " + lines);
  return lines;
}
countLines(document.getElementById("foo"));
div
{
  padding:100px 0 10% 0;
  background: pink;
  box-sizing: border-box;
  border:30px solid red;
}
<div id="foo">
x<br>
x<br>
x<br>
x<br>
</div>

很好的考虑,但在我的情况下,一行 div 的高度比行高高 1px,没有任何填充和边框。因此,通过结合您的答案和@e-info128 的答案(cloneNode 方法)来获取行高可能是更好的选择
2021-03-14 13:20:52
有用的帖子...谢谢
2021-03-29 13:20:52

克隆容器对象并写入 2 个字母并计算高度。这将返回应用了所有样式的实际高度、行高等。现在,计算高度对象/字母的大小。在 Jquery 中,高度优于 padding、margin 和 border,计算每行的实际高度非常棒:

other = obj.clone();
other.html('a<br>b').hide().appendTo('body');
size = other.height() / 2;
other.remove();
lines = obj.height() /  size;

如果您使用每个字母高度不同的稀有字体,这将不起作用。但适用于所有普通字体,如 Arial、mono、comics、Verdana 等。使用您的字体进行测试。

例子:

<div id="content" style="width: 100px">hello how are you? hello how are you? hello how are you?</div>
<script type="text/javascript">
$(document).ready(function(){

  calculate = function(obj){
    other = obj.clone();
    other.html('a<br>b').hide().appendTo('body');
    size = other.height() / 2;
    other.remove();
    return obj.height() /  size;
  }

  n = calculate($('#content'));
  alert(n + ' lines');
});
</script>

结果: 6 Lines

适用于所有浏览器,没有超出标准的罕见功能。

检查:https : //jsfiddle.net/gzceamtr/

首先,我想说非常感谢你,正是我一直在寻找的。你能解释一下计算函数的每一行吗?非常感谢。SYA :)
2021-04-02 13:20:52
对于那些需要非 jQuery 答案的人:clonecloneNodehidestyle.visibility = "hidden"html('a<br>b')textContent='a\r\nb'appendTo('body')document.documentElement.appendChildheight()getBoundingClientRect().height
2021-04-06 13:20:52
由于我在行高和 div 高度之间得到 1px 的误差,我推荐这个答案。结合这个和@Jeff 的答案会更好
2021-04-06 13:20:52