How can I count text lines inside an DOM element? Can I?
If the div's size is dependent on the content (which I assume to be the case from your description) then you can retrieve the div's height using:
var divHeight = document.getElementById('content').offsetHeight;
And divide by the font line height:
document.getElementById('content').style.lineHeight;
Or to get the line height if it hasn't been explicitly set:
var element = document.getElementById('content');
document.defaultView.getComputedStyle(element, null).getPropertyValue("lineHeight");
You will also need to take padding and inter-line spacing into account.
EDIT
Fully self-contained test, explicitly setting line-height:
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>
Check out the function getClientRects() which can be used to count the number of lines in an element. Here is an example of how to use it.
var message_lines = $("#message_container")[0].getClientRects();
It returns a javascript DOM object. The amount of lines can be known by doing this:
var amount_of_lines = message_lines.length;
A few things to note is it only works if the containing element is inline, however you can surround the containing inline element with a block element to control the width like so:
console.log( message_container.getClientRects().length )
<div style="display:inline;" id="message_container">
..Text of the post..<br>
nice ha?
</div>
Though I don't recommend hard coding the style like that. It's just for example purposes.
One solution is to enclose every word in a span tag using script. Then if the Y dimension of a given span tag is less than that of it's immediate predecessor then a line break has occurred.
I wasnt satisfied with the answers here and on other questions. The highest rated answer doesn't take padding
or border
into account, and therefore obviously ignores box-sizing
as well. My answer combines some techniques here and and on other threads to get a solution that works to my satisfaction.
It isnt perfect: When no numerical value was able to be retrieved for the line-height
(e.g. normal
or inherit
), it just uses the font-size
multiplied by 1.2
. Perhaps someone else can suggest a reliable way to detect the pixel value in those cases.
Other than that, it has been able to correctly handle most of the styles and cases I have thrown at it.
jsFiddle for playing around and testing. Also inline below.
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>
Clone the container object and write 2 letters and calculate the height. This return the real height with all style applied, line height, etc. Now, calculate the height object / the size of a letter. In Jquery, the height excelude the padding, margin and border, it is great to calculate the real height of each line:
other = obj.clone();
other.html('a<br>b').hide().appendTo('body');
size = other.height() / 2;
other.remove();
lines = obj.height() / size;
If you use a rare font with different height of each letter, this does not works. But works with all normal fonts, like Arial, mono, comics, Verdana, etc. Test with your font.
Example:
<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>
Result: 6 Lines
Works in all browser without rare functions out of standards.
Check: https://jsfiddle.net/gzceamtr/