如何计算等宽字体中适合放入div的字符数

3

我有这样的代码:

div {
    font-family: monospace;
    font-size: 12px;
    line-height: 14px;
}

$(function() {
    var div = $('div');
    var space = $('<span>&nbsp;</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();
});

但是字符数量太少,无法填满div的宽度。有人知道如何计算填充div一行所需的字符数吗?

4个回答

3

如何计算每行字符数(CPL)

enter image description here

使用JS获取包含变量“75”的div的宽度,以及您的字体大小和容器宽度。但是这就是公式。

  • 75 = 所需CPL
  • 16 = 字体大小
  • 2.28 = 字符常量 - 在您的情况下,这将是等宽字体的字符常量
  • 526.3158 = 容器的PX值。

制作一个函数来操作此公式以获得答案。

阅读更多 >


这个公式基于等宽字体中字符的(前进)宽度与字体大小的假设。这只是一个猜测/假设/估计,不再多说。如果您打算使用JavaScript进行操作,可以访问实际宽度,因此没有理由依赖这些问题。 - Jukka K. Korpela

1
这里有一个通用的方法,它使用getClientRects()来确定内容何时溢出到新行。似乎需要使用normalize()使getClientRects()正常工作。
我使用word-wrap: break-word来避免需要多个
您还可以通过使用我使用的Array().join()方法简化for循环:

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>


1
使用简单方法的问题在于,尽管等宽字体中字符的前进宽度是恒定的,但通常不是像素的整数倍。它在字体文件中以更细粒度的方式定义,通常使用字体大小的千分之一作为单位。浏览器以不同的方式处理这个问题。问题中的代码在不同的浏览器中表现不同。
为了获得一致的结果,请设置一个内联元素,在
元素内插入它,并添加字符,直到其宽度超过容器的宽度;然后只需删除最后一个字符即可。这在普通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>


不使用 innerHTML,是否有可能获取字符数量?我需要在窗口调整大小时计算它,但当我调整大小时,我的浏览器会冻结。 - jcubic
我认为你无法在不实际创建包含足够多字符的元素的情况下获得可靠的值。如果需要,您可以将其设置为不可见。如果浏览器冻结,则问题在其他地方(例如,您尝试在未将“span”添加到文档中的情况下使用代码;这是行不通的,因为它的宽度将保持为零)。 - Jukka K. Korpela

0
我的解决方案是使用getBoundingClientRect获取一个字符的实际浮动宽度,然后只需使用容器的宽度除以字符的宽度即可。
function get_char_size(div) {
    var temp = $('<span>&nbsp;</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);

有两个函数,因为如果您不更改字体大小,则只能计算字符大小一次,第二个函数可以在每次调整容器大小时使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接