Reputation: 66490
I have code like this:
div {
font-family: monospace;
font-size: 12px;
line-height: 14px;
}
$(function() {
var div = $('div');
var space = $('<span> </span>').appendTo(div);
var num_chars = div.width() / space.width();
var chars = '';
for (var i=0; i<num_chars; ++i) {
chars += 'd';
}
div.html(chars);
space.remove();
});
but number of characters is way to small to fill the width of the div. Anyone know how to calculate the number of characters that will fill one line of a div?
Upvotes: 3
Views: 3222
Reputation: 66490
My solution that works was using getBoundingClientRect to get real float width of one character and then just use width of the container divided by width of the character:
function get_char_size(div) {
var temp = $('<span> </span>').appendTo(div);
var rect = temp.find('span')[0].getBoundingClientRect();
var result = {
width: rect.width,
height: rect.height
};
temp.remove();
return result;
}
function get_num_chars(div, char_size) {
var width = div.width();
return Math.floor(width / char_size.width);
}
var container = $('.container');
var size = get_char_size(container);
var chars_per_line = get_num_chars(container, size);
there are two functions because if you don't change font size you can calculate char size only once and second function can use each time you resize the container.
Upvotes: 0
Reputation: 201568
The problem with the simple approach is that although the advance width of a character is constant in a monospace font, it is generally not an integer number of pixels. It is defined in a much more fine-grained manner in the font file, typically using a unit that is one thousandth of the font size. Browsers deal with this in different ways. The code in the question behaves differently in different browsers.
For consistent results, set up an inline element, insert it inside the div
element, and add characters to it until its width exceeds the width of the container; then just remove the last character. This is rather easy in plain JavaScript:
var foo = document.getElementById('foo');
var len = foo.offsetWidth;
var span = document.createElement('span');
foo.appendChild(span);
span.innerHTML = '';
for(var i = 0; span.offsetWidth <= len; i++)
span.innerHTML += 'd';
span.innerHTML = span.innerHTML.substring(0, span.innerHTML.length - 1);
span, div {
font-family: monospace;
font-size: 12px; /* kept this, though it is irrelevant */
/* line-height: 14px; omitted here as irrelevant */
}
<div id=foo></div>
Upvotes: 1
Reputation: 35670
Here's a general method, which uses getClientRects() to determine when the contents overflow to a new line. normalize() seems to be needed for getClientRects()
to function properly.
I'm using word-wrap: break-word
to avoid the need for multiple spans.
You can also simplify the for
loop by using the Array().join()
method I use:
var space = $('<span>').appendTo('div'),
num_chars;
do {
space.append('M');
space[0].normalize();
} while (space[0].getClientRects().length === 1);
num_chars = space.text().length;
$('div').html(Array(num_chars).join('d'));
div {
font-family: monospace;
font-size: 12px;
width: 400px;
border: 1px solid black;
}
span {
word-wrap: break-word;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
Upvotes: 1
Reputation: 7746
How to Calculate CPL
Use JS to get the width of the div where 75
would become a variable as well as your fontsize and container width. But this is the formula.
Make a function to manipulate this formula to get your answer.
Upvotes: 3