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

but*_*oxa 112 html javascript dom

我想知道是否有办法计算div中的行数.假设我们有这样的div:

<div id="content">hello how are you?</div>
Run Code Online (Sandbox Code Playgroud)

根据许多因素,div可以有一行,两行,甚至四行文本.脚本有什么方法可以知道吗?

换句话说,DOM中是否有自动中断?

Poo*_*ool 76

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

var divHeight = document.getElementById('content').offsetHeight;
Run Code Online (Sandbox Code Playgroud)

并除以字体行高:

document.getElementById('content').style.lineHeight;
Run Code Online (Sandbox Code Playgroud)

或者,如果尚未明确设置,则获取行高:

var element = document.getElementById('content');
document.defaultView.getComputedStyle(element, null).getPropertyValue("lineHeight");
Run Code Online (Sandbox Code Playgroud)

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

编辑

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

function countLines() {
   var el = document.getElementById('content');
   var divHeight = el.offsetHeight
   var lineHeight = parseInt(el.style.lineHeight);
   var lines = divHeight / lineHeight;
   alert("Lines: " + lines);
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 这是一个好的开始,除了可能并不总是设置行高.你应该从元素的计算样式中得到它. (7认同)
  • 这可能只适用于最简单的情况(如我的例子).如果内部有跨距,内联块元素等,则直接除以(父)字体大小是没有价值的.不过,谢谢,它总比没有好. (6认同)
  • @Chetan - 设置文本尺寸(以像素为单位)通常被认为是一件坏事.http://www.astahost.com/Sizes-Webdesign-Em-Vs-Px-t8926.html (5认同)
  • 我认为获得计算的“line-height”(未明确设置)的更好方法是使用“window.getComputedStyle(element, null).getPropertyValue('line-height')” (2认同)

小智 18

一种解决方案是使用脚本将每个单词括在span标记中.然后,如果给定span标记的Y维度小于其前一个标记的Y维度,则会发生换行.

  • 再想一想,如果行中存在垂直对齐的跨度,则此方法会失败。因此,即使只有文本的段落也可能被错误地计数。 (2认同)

小智 16

查看函数getClientRects(),它可用于计算元素中的行数.以下是如何使用它的示例.

var message_lines = $("#message_container")[0].getClientRects();
Run Code Online (Sandbox Code Playgroud)

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

var amount_of_lines = message_lines.length;
Run Code Online (Sandbox Code Playgroud)

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

console.log("");
console.log("message_lines");
console.log(".............................................");
console.dir(message_lines);
console.log("");
Run Code Online (Sandbox Code Playgroud)

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

<div style="width:300px;" id="block_message_container">
<div style="display:inline;" id="message_container">
..Text of the post..
</div>
</div>
Run Code Online (Sandbox Code Playgroud)

虽然我不建议硬编码这样的风格.这只是为了举例.

  • @klm123您需要将元素设置为“display: inline” (3认同)
  • 这个和其他基于getClientRects的答案远胜于公认的答案 (2认同)
  • 这应该是公认的答案。谢谢@Digital-Christie (2认同)
  • getClientRects().length 在 Opera 和 Chrome 中总是为我返回 1 (2认同)

Jef*_*eff 12

我不满意这里的答案和其他问题.得分最高的答案没有考虑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"));
Run Code Online (Sandbox Code Playgroud)
div
{
  padding:100px 0 10% 0;
  background: pink;
  box-sizing: border-box;
  border:30px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<div id="foo">
x<br>
x<br>
x<br>
x<br>
</div>
Run Code Online (Sandbox Code Playgroud)


e-i*_*128 8

克隆容器对象并写入2个字母并计算高度.这将返回所有应用的样式,行高等实际高度.现在,计算高度对象/字母的大小.在Jquery中,高度除了填充,边距和边框之外,计算每条线的实际高度非常棒:

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

如果您使用每个字母高度不同的稀有字体,则不起作用.但适用于所有普通字体,如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>
Run Code Online (Sandbox Code Playgroud)

结果: 6 Lines

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

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

  • 对于那些需要非 jQuery 答案的人:`clone`→`cloneNode`、`hide`→`style.visibility = "hidden"`、`html('a&lt;br&gt;b')`→`textContent='a\ r\nb'`, `appendTo('body')`→`document.documentElement.appendChild`, `height()`→`getBoundingClientRect().height` (3认同)

but*_*oxa 6

我确信现在不可能.但是,它是.

IE7的getClientRects实现完全符合我的要求.在IE8中打开此页面,尝试刷新不同的窗口宽度,并查看第一个元素中的行数如何相应地更改.这是该页面的javascript的关键行:

var rects = elementList[i].getClientRects();
var p = document.createElement('p');
p.appendChild(document.createTextNode('\'' + elementList[i].tagName + '\' element has ' + rects.length + ' line(s).'));
Run Code Online (Sandbox Code Playgroud)

不幸的是,Firefox总是为每个元素返回一个客户端矩形,IE8现在也是这样做的.(Martin Honnen的页面今天有效,因为IE在IE compat视图中呈现它;在IE8中按F12以使用不同的模式.)

这真是难过;这真是伤心.看起来Firefox的文字但毫无价值的规范实现再次赢得了微软的实用价值.或者我是否会错过新的getClientRects可以帮助开发人员的情况?

  • 正如Mozilla的[element.getClientRects](https://developer.mozilla.org/en/DOM/element.getClientRects)文档所指出的那样,至少对于_inline_元素,W3C规范*确实*导致每行的一个矩形文字 - 不理想,但至少是一些东西. (2认同)

pen*_*sky 6

对于那些使用jQuery http://jsfiddle.net/EppA2/3/的人

function getRows(selector) {
    var height = $(selector).height();
    var line_height = $(selector).css('line-height');
    line_height = parseFloat(line_height)
    var rows = height / line_height;
    return Math.round(rows);
}
Run Code Online (Sandbox Code Playgroud)

  • 当jQuery从`$(selector).css('line-height');`返回"normal"时,你不会从该函数中得到一个数字. (8认同)

小智 5

基于 GuyPaddock 上面的回答,这似乎对我有用

function getLinesCount(element) {
  var prevLH = element.style.lineHeight;
  var factor = 1000;
  element.style.lineHeight = factor + 'px';

  var height = element.getBoundingClientRect().height;
  element.style.lineHeight = prevLH;

  return Math.floor(height / factor);
}
Run Code Online (Sandbox Code Playgroud)

这里的技巧是增加行高,以至于它会“吞噬”任何浏览器/操作系统在呈现字体的方式上的差异

用各种样式和不同的字体大小/系列检查它唯一没有考虑的事情(因为在我的情况下它无关紧要)是填充 - 可以轻松添加到解决方案中。