测量字符串的长度

在某些业务场景下,我们需要获取字符串的长度,比如根据字符串的长度来放置它们本身、比如根据文字长度设置横向滚动、比如虚拟光标,等等…

利用隐藏元素

需要注意的就是display: none;visibility: hidden;的区别

1
<span id="txtWidth"></span>
1
2
3
4
5
6
7
#txtWidth {
/* 避免干扰其他内容 */
position: absolute;
z-index: -999;
/* 不能用display: none,否则测量结果永远是0 */
visibility: hidden;
}
1
2
3
4
5
6
7
let str = "这是1要2测量,的文字"
let txtWidth = document.querySelector('#txtWidth')
// 注意设置字体
txtWidth.style.fontSize = '12px'
txtWidth.style.fontFamily = "PingFangSC-Regular"
txtWidth.textContent = str
let strLength = txtWidth.offsetWidth

利用Canvas

Canvas不仅仅可以用来画图。以下2种做法都是可以的

  1. 从上面的做法很自然的想到用一个Canvas标签,区别是这Canvas是可以用display: none

    1
    <canvas id="wrapper" style="display: none;"></canvas>
    1
    2
    3
    4
    5
    6
    let str = "这是1要2测量,的文字"
    let canvas = document.getElementById('wrapper');
    let ctx = canvas.getContext("2d");
    // 字体的设置要和实际要测量的保持一致。
    ctx.font = '12px PingFangSC-Regular';
    let strLength = Math.ceil(ctx.measureText(str).width);
  2. 既然Canvas可以用display: none,很自然的想到我们也许不需要一个真的标签,纯js方法也可以封装到一个函数里去

    1
    2
    3
    4
    5
    6
    7
    8
    let str = "这是1要2测量,的文字"
    function measureText(str) {
    let canvas = document.createElement('canvas')
    let ctx = canvas.getContext("2d");
    ctx.font = '12px PingFangSC-Regular';
    let strLength = Math.ceil(ctx.measureText(str).width);
    return strLength
    }

一点小问题

TODO: 用span标签测量出来的长度,会比用canvas标签测量出来的长度小1px。